C++学习17、对象的创建、初始化和使用

在理解了类的基础上,我们现在深入探讨C++对象的创建、初始化和使用。对于初学者来说,掌握这些步骤是理解面向对象编程(OOP)的关键。

1. 对象的创建

在C++中,对象的创建是通过类名后跟一对圆括号来实现的。这个过程称为实例化,即根据类模板创建一个具体的对象。下面是一个简单的例子:

#include <iostream>
#include <string>
 
class Person {
public:
    std::string name;
    int age;
 
    // 构造函数
    Person(std::string n, int a) : name(n), age(a) {}
 
    // 显示信息的方法
    void display() {
        std::cout << "Name: " << name << ", Age: " << age << std::endl;
    }
};
 
int main() {
    // 创建对象
    Person person1("Alice", 30);
    Person person2("Bob", 25);
 
    // 使用对象的方法
    person1.display();
    person2.display();
 
    return 0;

}

在这个例子中,Person类有两个数据成员:name和age,以及一个构造函数Person(std::string n, int a)用于初始化这两个成员。在main函数中,我们创建了两个Person对象:person1和person2,并通过调用它们的display方法来显示信息。

2. 对象的初始化

对象的初始化通常是通过构造函数来完成的。构造函数是一种特殊的成员函数,它在对象创建时自动调用。构造函数的名字与类名相同,且没有返回类型。

2.1 默认构造函数

如果一个类没有定义任何构造函数,编译器会自动生成一个默认构造函数。默认构造函数不接受任何参数,并且不执行任何初始化操作(对于基本数据类型,成员变量会被初始化为不确定的值)。

class MyClass {
public:
    int value;
};
 
int main() {
    MyClass obj; // 调用默认构造函数
    // obj.value 的值是未定义的
    return 0;

}

为了避免未定义行为,我们通常建议为类提供自己的构造函数,即使是一个简单的默认初始化。

2.2 带参数的构造函数

在前面的例子中,我们已经展示了如何定义一个带参数的构造函数。通过参数列表,我们可以在对象创建时初始化其成员变量。

class Point {
public:
    int x, y;
 
    // 带参数的构造函数
    Point(int a, int b) : x(a), y(b) {}
};
 
int main() {
    Point p(10, 20); // 调用带参数的构造函数
    // p.x = 10, p.y = 20
    return 0;

}

2.3 初始化列表

在构造函数中,我们可以使用初始化列表来初始化成员变量。初始化列表位于构造函数参数列表之后,成员变量初始化之前,由冒号:开始。

class Rectangle {
public:
    int width, height;
 
    // 使用初始化列表
    Rectangle(int w, int h) : width(w), height(h) {}
};
 
int main() {
    Rectangle rect(30, 40); // 调用构造函数并使用初始化列表
    // rect.width = 30, rect.height = 40
    return 0;

}

使用初始化列表通常比在构造函数体内赋值更高效,特别是对于常量成员变量和引用成员变量,它们必须在初始化列表中初始化。

class Rectangle {
public:
    int width, height;
 
    // 使用初始化列表
    Rectangle(int w, int h) : width(w), height(h) {}
};
 
int main() {
    Rectangle rect(30, 40); // 调用构造函数并使用初始化列表
    // rect.width = 30, rect.height = 40
    return 0;

}


2.4 拷贝构造函数

拷贝构造函数是一个特殊的构造函数,它接受一个同类型的对象作为参数,并用于创建一个新的对象作为该对象的副本。

class StringCopy {
public:
    char* str;
 
    // 普通构造函数
    StringCopy(const char* s) {
        str = new char[strlen(s) + 1];
        strcpy(str, s);
    }
 
    // 拷贝构造函数
    StringCopy(const StringCopy& other) {
        str = new char[strlen(other.str) + 1];
        strcpy(str, other.str);
    }
 
    // 析构函数
    ~StringCopy() {
        delete[] str;
    }
};
 
int main() {
    StringCopy str1("Hello");
    StringCopy str2 = str1; // 调用拷贝构造函数
    // 现在str1和str2都指向包含"Hello"的字符串
    return 0;

}

在上面的例子中,StringCopy类有一个普通构造函数和一个拷贝构造函数。当我们尝试用一个已存在的StringCopy对象来初始化另一个StringCopy对象时(如StringCopy str2 = str1;),拷贝构造函数会被调用。

3. 对象的使用

创建了对象并初始化后,我们就可以通过点操作符.来访问对象的成员变量和成员函数了。

class Car {
public:
    std::string make;
    std::string model;
    int year;
 
    void drive() {
        std::cout << make << " " << model << " (" << year << ") is driving." << std::endl;
    }
};
 
int main() {
    Car myCar;
    myCar.make = "Toyota";
    myCar.model = "Camry";
    myCar.year = 2020;
 
    myCar.drive(); // 输出: Toyota Camry (2020) is driving.
 
    return 0;

}

在这个例子中,我们创建了一个Car对象myCar,并通过点操作符设置了其成员变量make、model和year的值。然后,我们调用了myCar的drive方法来显示一条消息。

4. 对象的销毁

对象的生命周期从创建开始,到销毁结束。当对象超出其作用域或显式删除时,它的析构函数会被调用。析构函数是一个特殊的成员函数,它在对象销毁时自动调用,用于执行清理工作,如释放动态分配的内存。

class MyClass {
public:
    ~MyClass() {
        std::cout << "MyClass destructor called." << std::endl;
    }
};
 
int main() {
    MyClass obj; // 创建对象时,构造函数被调用(但这里没有显式定义构造函数)
    // 当main函数结束时,obj超出作用域,析构函数被调用
    return 0;

}

在上面的例子中,MyClass类有一个析构函数,它在对象obj销毁时被调用。输出将是:

MyClass destructor called.

对于动态分配的对象(使用new关键字创建的对象),我们需要使用delete关键字来显式销毁它们,并调用析构函数。

class MyClass {
public:
    ~MyClass() {
        std::cout << "MyClass destructor called." << std::endl;
    }
};
 
int main() {
    MyClass* obj = new MyClass(); // 动态创建对象
    // ... 使用对象 ...
    delete obj; // 显式销毁对象,调用析构函数
    return 0;

}

在这个例子中,我们动态创建了一个MyClass对象obj,并在使用完毕后使用delete关键字来销毁它。输出同样将是:

MyClass destructor called.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值