What is a Class Declaration?
A class declaration in C++ is a statement that introduces a new class name and specifies its members (data and functions). It defines the blueprint or template for objects that will be created from this class.
Basic Syntax of Class Declaration
class ClassName {
// Access specifier
private:
// Private members
protected:
// Protected members
public:
// Public members
}; // Don't forget the semicolon at the end
The semicolon at the end of the class declaration is mandatory.
Parts of a Class Declaration
A complete class declaration consists of:
- Class keyword: The keyword
classthat starts the declaration - Class name: A unique identifier for the class
- Body: Content enclosed in curly braces
{} - Access specifiers:
private,protected, andpublicsections - Class members: Data members and member functions
- Ending semicolon: The
;character that terminates the declaration
Simple Class Declaration Example
class Rectangle {
private:
double length;
double width;
public:
// Constructor
Rectangle(double l, double w);
// Member functions
void setDimensions(double l, double w);
double calculateArea();
double calculatePerimeter();
};
Forward Declaration of a Class
Sometimes, you may need to mention a class before its full declaration. This is called a forward declaration and is done like this:
class ClassName; // Forward declaration
Forward declarations are useful when:
- Two classes refer to each other (circular dependency)
- You only need a pointer or reference to the class, not the full definition
Example:
// Forward declaration
class B;
// Class A refers to class B
class A {
private:
B* pointerToB; // This is fine with just a forward declaration
public:
void setB(B* b);
};
// Full declaration of class B
class B {
private:
A* pointerToA;
public:
void setA(A* a);
};
Class Declaration vs. Class Definition
In C++, there’s a distinction between class declaration and definition:
- Class Declaration: Introduces the class name and its members
- Class Definition: Provides the implementation of member functions
You can separate these for better organization:
// Class declaration (usually in a header file .h)
class Circle {
private:
double radius;
public:
void setRadius(double r);
double getRadius();
double calculateArea();
};
// Class definition (usually in a source file .cpp)
void Circle::setRadius(double r) {
radius = r;
}
double Circle::getRadius() {
return radius;
}
double Circle::calculateArea() {
return 3.14159 * radius * radius;
}
Class Declaration in Header Files
It’s common practice to put class declarations in header files (.h or .hpp) and definitions in source files (.cpp):
Circle.h
#ifndef CIRCLE_H
#define CIRCLE_H
class Circle {
private:
double radius;
public:
Circle(double r = 0.0); // Constructor with default parameter
void setRadius(double r);
double getRadius() const;
double calculateArea() const;
double calculateCircumference() const;
};
#endif
Circle.cpp
#include "Circle.h"
#include <cmath>
Circle::Circle(double r) {
radius = r;
}
void Circle::setRadius(double r) {
radius = r;
}
double Circle::getRadius() const {
return radius;
}
double Circle::calculateArea() const {
return M_PI * radius * radius;
}
double Circle::calculateCircumference() const {
return 2 * M_PI * radius;
}
Nested Class Declaration
You can declare a class inside another class:
class Outer {
private:
int outerData;
public:
// Nested class declaration
class Inner {
private:
int innerData;
public:
Inner(int data);
void display();
};
Inner createInner(int data);
};
// Definition of Inner constructor
Outer::Inner::Inner(int data) {
innerData = data;
}
// Definition of Inner member function
void Outer::Inner::display() {
std::cout << "Inner data: " << innerData << std::endl;
}
// Definition of Outer member function that returns an Inner object
Outer::Inner Outer::createInner(int data) {
return Inner(data);
}
Template Class Declaration
You can declare a class with type parameters (templates):
template <typename T>
class Container {
private:
T data;
public:
Container(T value);
T getValue() const;
void setValue(T value);
};
// Definition of template class methods
template <typename T>
Container<T>::Container(T value) {
data = value;
}
template <typename T>
T Container<T>::getValue() const {
return data;
}
template <typename T>
void Container<T>::setValue(T value) {
data = value;
}
Access Specifiers in Detail
The three access specifiers in a class declaration control who can access the members:
-
private:
- Accessible only within the class itself
- Cannot be accessed from outside the class, even by derived classes
- Default access level if not specified
-
protected:
- Accessible within the class itself
- Accessible in derived classes
- Not accessible from outside the class hierarchy
-
public:
- Accessible from anywhere
- No restrictions on access
class MyClass {
private:
int privateVar; // Only accessible within MyClass
protected:
int protectedVar; // Accessible in MyClass and its derived classes
public:
int publicVar; // Accessible from anywhere
};
class DerivedClass : public MyClass {
public:
void accessTest() {
// privateVar = 10; // Error! Cannot access private members
protectedVar = 20; // OK, can access protected members
publicVar = 30; // OK, can access public members
}
};
int main() {
MyClass obj;
// obj.privateVar = 10; // Error! Cannot access private members
// obj.protectedVar = 20; // Error! Cannot access protected members
obj.publicVar = 30; // OK, can access public members
return 0;
}
Member Specifiers
You can use additional specifiers in class declarations:
- static: Members that belong to the class as a whole, not to specific objects
- const: Member functions that don’t modify the object’s state
- virtual: Functions that can be overridden in derived classes
- friend: Functions or classes that can access private members
class Example {
private:
int regularVar;
static int staticVar; // Shared among all objects
public:
void regularFunction();
static void staticFunction(); // Can be called without an object
void constFunction() const; // Cannot modify the object
virtual void virtualFunction(); // Can be overridden
friend void friendFunction(Example& e); // Not a member but can access private members
friend class FriendClass; // Another class with access rights
};
Best Practices for Class Declarations
- Use meaningful class names: Name should reflect what the class represents
- Keep related items together: Group related members in the same section
- Put public members first: Most code only interacts with the public interface
- Use comments: Document what the class and its members do
- Make data members private: Enforce encapsulation
- Use const for methods: Mark methods that don’t modify the object as const
- Avoid friendships when possible: They break encapsulation
- Separate declaration and definition: Use header and source files
Example of a Well-Declared Class
// StudentRecord.h
#ifndef STUDENT_RECORD_H
#define STUDENT_RECORD_H
#include <string>
#include <vector>
class StudentRecord {
public:
// Constructors
StudentRecord();
StudentRecord(const std::string& name, int id);
// Accessors (getters)
std::string getName() const;
int getID() const;
double getGPA() const;
// Mutators (setters)
void setName(const std::string& name);
void setID(int id);
// Behavior methods
void addGrade(char grade);
void displayRecord() const;
bool isHonorStudent() const;
private:
// Data members
std::string studentName;
int studentID;
std::vector<char> grades;
// Helper methods
double calculateGPA() const;
double getPointsForGrade(char grade) const;
};
#endif
Summary
Class declaration in C++ is a fundamental concept in object-oriented programming. It defines the structure and behavior of objects by specifying data members and member functions. Understanding how to properly declare classes is essential for creating well-structured and maintainable C++ code. A good class declaration should follow principles of encapsulation, provide a clear interface, and separate implementation details from the public interface.