What is an Object?
An object is an instance of a class. When you declare an object, you’re creating a variable of the class type that has its own memory space for storing the data members defined in the class.
Basic Object Declaration Syntax
ClassName objectName;
This creates an object named objectName of the class ClassName.
Different Ways to Declare Objects
1. Simple Declaration
class Student {
public:
string name;
int rollNumber;
};
int main() {
Student student1; // Simple declaration of an object
return 0;
}
2. Declaration with Initialization (Using Constructor)
class Student {
public:
string name;
int rollNumber;
// Constructor
Student(string n, int r) {
name = n;
rollNumber = r;
}
};
int main() {
Student student1("John", 101); // Declaring with initialization
return 0;
}
3. Dynamic Object Creation (Using Pointers)
class Student {
public:
string name;
int rollNumber;
};
int main() {
Student* studentPtr = new Student; // Create object dynamically
// Use the object through the pointer
studentPtr->name = "Alice";
studentPtr->rollNumber = 102;
// Don't forget to free the memory when done
delete studentPtr;
return 0;
}
4. Creating Arrays of Objects
class Point {
public:
int x, y;
Point() {
x = 0;
y = 0;
}
Point(int a, int b) {
x = a;
y = b;
}
};
int main() {
// Array of 5 Point objects (using default constructor)
Point pointsArray[5];
// Initialize specific elements
pointsArray[0].x = 10;
pointsArray[0].y = 20;
// Dynamic array of objects
Point* pointsDynamic = new Point[5];
pointsDynamic[1].x = 30;
pointsDynamic[1].y = 40;
// Don't forget to delete the dynamic array
delete[] pointsDynamic;
return 0;
}
5. Declaration with Uniform Initialization (C++11 and later)
class Rectangle {
public:
double length;
double width;
Rectangle(double l, double w) {
length = l;
width = w;
}
};
int main() {
// Uniform initialization syntax
Rectangle rect1{5.0, 3.0};
// Also valid
Rectangle rect2 = {6.0, 4.0};
return 0;
}
Memory Allocation for Objects
When you declare an object, memory is allocated for:
- All the data members of the class
- The object itself (which may include some overhead)
Member functions are not duplicated for each object. They are stored once in memory and shared by all objects of the class.
class Person {
private:
string name; // Memory allocated for each object
int age; // Memory allocated for each object
public:
void display() { /* Function code - stored once */ }
void setAge(int a) { age = a; }
};
int main() {
Person person1; // Memory allocated for name and age
Person person2; // Separate memory allocated for name and age
// Both person1 and person2 share the same function code
return 0;
}
Accessing Object Members
Using the Dot Operator (.)
For objects declared directly, use the dot operator to access members:
class Student {
public:
string name;
int rollNumber;
void display() {
cout << "Name: " << name << ", Roll: " << rollNumber << endl;
}
};
int main() {
Student s1;
// Accessing data members
s1.name = "John";
s1.rollNumber = 101;
// Accessing member function
s1.display();
return 0;
}
Using the Arrow Operator (->)
For objects created dynamically (using pointers), use the arrow operator:
int main() {
Student* s2 = new Student;
// Accessing data members through pointer
s2->name = "Alice";
s2->rollNumber = 102;
// Accessing member function through pointer
s2->display();
delete s2;
return 0;
}
Object Initialization
Objects can be initialized in several ways:
1. Using Constructors
class Circle {
private:
double radius;
public:
// Default constructor
Circle() {
radius = 0.0;
}
// Parameterized constructor
Circle(double r) {
radius = r;
}
};
int main() {
Circle c1; // Uses default constructor
Circle c2(5.0); // Uses parameterized constructor
Circle c3 = 7.5; // Also uses parameterized constructor
return 0;
}
2. Using Initialization Lists (C++11 and later)
Circle c4 = {}; // Default initialization
Circle c5 = {10.0}; // Initialize with radius 10.0
3. Using Copy Constructor
Circle c6 = c2; // Creates c6 as a copy of c2
Circle c7(c2); // Also creates a copy
Special Cases of Object Declaration
1. Declaring const Objects
A const object’s data members cannot be modified after initialization:
class Temperature {
private:
double celsius;
public:
Temperature(double c) : celsius(c) {}
double getCelsius() const {
return celsius;
}
double getFahrenheit() const {
return celsius * 9.0/5.0 + 32.0;
}
};
int main() {
const Temperature freezing(0.0);
// These are allowed because the methods are const
double c = freezing.getCelsius();
double f = freezing.getFahrenheit();
// This would cause an error
// freezing.celsius = 100.0;
return 0;
}
2. Objects as Function Parameters
class Point {
public:
int x, y;
Point(int a = 0, int b = 0) {
x = a;
y = b;
}
};
// Passing object by value (a copy is made)
void displayByValue(Point p) {
cout << "Point: (" << p.x << ", " << p.y << ")" << endl;
}
// Passing object by reference (no copy is made)
void displayByReference(const Point& p) {
cout << "Point: (" << p.x << ", " << p.y << ")" << endl;
}
int main() {
Point p1(10, 20);
displayByValue(p1); // Creates a copy of p1
displayByReference(p1); // Uses the original p1
return 0;
}
3. Objects as Function Return Types
class Complex {
public:
double real;
double imag;
Complex(double r = 0.0, double i = 0.0) {
real = r;
imag = i;
}
};
// Function that returns an object
Complex addComplex(const Complex& a, const Complex& b) {
Complex result;
result.real = a.real + b.real;
result.imag = a.imag + b.imag;
return result;
}
int main() {
Complex c1(3.0, 4.0);
Complex c2(1.0, 2.0);
Complex sum = addComplex(c1, c2);
cout << "Sum: " << sum.real << " + " << sum.imag << "i" << endl;
return 0;
}
Anonymous Objects
You can create objects without names (anonymous objects) for temporary use:
class Message {
private:
string text;
public:
Message(string t) {
text = t;
cout << "Message created: " << text << endl;
}
~Message() {
cout << "Message destroyed: " << text << endl;
}
};
int main() {
// Anonymous object - created and destroyed in the same statement
Message("Hello World");
cout << "After anonymous object" << endl;
return 0;
}
Output:
Message created: Hello World
Message destroyed: Hello World
After anonymous object
Common Errors When Declaring Objects
- Forgetting to initialize: Objects may contain garbage values if not initialized
- Memory leaks: Not deleting dynamically allocated objects
- Using uninitialized pointers: Accessing members through null pointers
- Accessing private members: Trying to access private members directly
- Object slicing: Losing derived class information when assigning to base class objects
Best Practices
- Use constructors for initialization: Always initialize objects properly
- Prefer stack allocation: Use dynamic allocation only when necessary
- Use smart pointers: Consider using
std::unique_ptrorstd::shared_ptrinstead of raw pointers - Pass large objects by reference: Avoid unnecessary copying
- Use const where appropriate: Make objects const when they shouldn’t change
Summary
Declaring objects in C++ is the process of creating instances of classes. Objects can be created on the stack (automatic storage), dynamically on the heap, or as part of other data structures like arrays. Proper initialization through constructors ensures that objects start in a valid state. Understanding the different ways to declare and access objects is fundamental to effective C++ programming.