C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > c++ 类对象初始化

c++中类的对象初始化的实现示例

作者:start_up_go

C++对象初始化依赖构造函数,包含默认、带参、初始化列表、拷贝及C++11的列表和委托构造等方法,聚合类与new动态初始化亦适用,初始化与赋值区别在于前者在创建时执行,后者在对象存在后修改,且const/引用成员仅能初始化

在 C++ 中,类的对象初始化是创建对象时为其成员变量赋予初始值的过程,核心依赖构造函数(类的特殊成员函数)。根据场景和需求,对象初始化有多种方式,下面详细介绍:

一、构造函数:初始化的核心

构造函数是与类同名的特殊成员函数,用于对象创建时的初始化,其特点:

二、对象初始化的具体方式

1. 默认初始化(无参构造函数)

当类有默认构造函数(无参构造函数)时,可直接创建对象,无需传递参数。

默认构造函数的来源:

示例

#include <iostream>
using namespace std;

class Person {
private:
    string name;
    int age;
public:
    // 手动定义默认构造函数
    Person() {
        name = "Unknown";
        age = 0;
        cout << "默认构造函数被调用" << endl;
    }

    void show() {
        cout << "Name: " << name << ", Age: " << age << endl;
    }
};

int main() {
    // 默认初始化(调用默认构造函数)
    Person p1;  // 正确:无参构造
    p1.show();  // 输出:Name: Unknown, Age: 0

    return 0;
}

注意:若手动定义了带参构造函数,编译器不再生成默认构造函数,此时需显式定义,否则Person p1;会报错。

2. 带参数的构造函数初始化

通过自定义带参数的构造函数,在创建对象时传递参数,直接初始化成员变量。

示例

class Person {
private:
    string name;
    int age;
public:
    // 带参数的构造函数
    Person(string n, int a) {
        name = n;  // 为成员变量赋值
        age = a;
        cout << "带参构造函数被调用" << endl;
    }

    void show() {
        cout << "Name: " << name << ", Age: " << age << endl;
    }
};

int main() {
    // 用带参构造函数初始化
    Person p2("Alice", 18);  // 直接传递参数
    p2.show();  // 输出:Name: Alice, Age: 18

    return 0;
}

3. 成员初始化列表(推荐)

构造函数的成员初始化列表用于在进入构造函数体之前,直接初始化成员变量(而非在函数体内赋值)。

适用场景

语法

类名(参数列表) : 成员1(值1), 成员2(值2), ... {
    // 构造函数体(可空)
}

示例

class Person {
private:
    string name;
    const int age;  // const成员,必须初始化
    int& id;        // 引用成员,必须初始化

public:
    // 成员初始化列表:直接初始化成员
    Person(string n, int a, int& i) : name(n), age(a), id(i) {
        // 构造函数体可做其他操作,无需再给成员赋值
        cout << "成员初始化列表被使用" << endl;
    }

    void show() {
        cout << "Name: " << name << ", Age: " << age << ", ID: " << id << endl;
    }
};

int main() {
    int num = 1001;
    Person p3("Bob", 20, num);  // 传递参数到初始化列表
    p3.show();  // 输出:Name: Bob, Age: 20, ID: 1001

    return 0;
}

优势:比在构造函数体内赋值更高效(直接初始化,而非先默认构造再赋值)。

4. 拷贝构造函数初始化

已存在的对象初始化新对象时,会调用拷贝构造函数

拷贝构造函数的语法(参数必须是同类对象的const引用):

类名(const 类名& 已有对象) {
    // 用已有对象的成员初始化当前对象的成员
}

调用场景

示例

class Person {
private:
    string name;
    int age;
public:
    // 带参构造函数
    Person(string n, int a) : name(n), age(a) {}

    // 拷贝构造函数(自定义)
    Person(const Person& other) {
        name = other.name;  // 拷贝other的name
        age = other.age;    // 拷贝other的age
        cout << "拷贝构造函数被调用" << endl;
    }

    void show() {
        cout << "Name: " << name << ", Age: " << age << endl;
    }
};

int main() {
    Person p4("Charlie", 22);  // 先创建p4
    Person p5 = p4;            // 用p4初始化p5(调用拷贝构造)
    Person p6(p4);             // 另一种写法(同样调用拷贝构造)

    p5.show();  // 输出:Name: Charlie, Age: 22
    p6.show();  // 输出:Name: Charlie, Age: 22

    return 0;
}

注意:若未手动定义拷贝构造函数,编译器会生成默认拷贝构造函数(浅拷贝)。若类中包含指针成员,浅拷贝可能导致内存问题(需手动实现深拷贝)。

5. 列表初始化(C++11 及以上)

使用大括号{} 初始化对象,支持多种场景,且更安全(防止窄化转换,如int不能隐式接收double的小数部分)。

示例

class Person {
private:
    string name;
    int age;
public:
    // 带参构造函数(支持列表初始化)
    Person(string n, int a) : name(n), age(a) {}
    void show() { cout << name << ", " << age << endl; }
};

int main() {
    // 列表初始化(调用带参构造)
    Person p7{"David", 25};  // 等价于 Person p7("David", 25);
    Person p8 = {"Eve", 26}; // 也支持等号+大括号

    p7.show();  // David, 25
    p8.show();  // Eve, 26

    return 0;
}

优势

6. 委托构造函数(C++11 及以上)

允许一个构造函数调用同一个类的另一个构造函数,减少代码重复。

示例

class Person {
private:
    string name;
    int age;
public:
    // 核心构造函数(带参数)
    Person(string n, int a) : name(n), age(a) {
        cout << "核心构造函数被调用" << endl;
    }

    // 委托构造:调用带参构造函数(默认name为"Unknown",age为0)
    Person() : Person("Unknown", 0) {
        cout << "委托构造函数(无参)被调用" << endl;
    }

    // 委托构造:调用带参构造函数(仅指定age,name默认"Guest")
    Person(int a) : Person("Guest", a) {
        cout << "委托构造函数(仅age)被调用" << endl;
    }
};

int main() {
    Person p9;      // 调用无参委托构造 → 核心构造
    Person p10(30); // 调用单参委托构造 → 核心构造
    return 0;
}

输出

核心构造函数被调用
委托构造函数(无参)被调用
核心构造函数被调用
委托构造函数(仅age)被调用

7. 聚合类的初始化

聚合类是一种特殊的类(或结构体),满足:

聚合类可直接用初始化列表初始化成员(按成员声明顺序)。

示例

// 聚合类(结构体,满足聚合类条件)
struct Student {
    string name;  // 公有成员
    int age;
    float score;
};

int main() {
    // 直接初始化聚合类的成员(按声明顺序)
    Student s1 = {"Frank", 19, 90.5};
    Student s2{"Grace", 20, 88.0};  // C++11列表初始化

    cout << s1.name << ", " << s1.age << ", " << s1.score << endl;  // Frank, 19, 90.5
    return 0;
}

8. 动态对象初始化(new关键字)

new创建堆上的对象时,需显式调用构造函数初始化,后续用delete释放。

示例

class Person {
private:
    string name;
public:
    Person(string n) : name(n) {}
    void show() { cout << name << endl; }
};

int main() {
    // 动态初始化(堆上创建对象)
    Person* p11 = new Person("Helen");  // 调用带参构造
    Person* p12 = new Person{"Ivy"};    // C++11列表初始化
    Person* p13 = new Person();         // 调用默认构造(若存在)

    p11->show();  // Helen
    p12->show();  // Ivy

    // 释放堆内存
    delete p11;
    delete p12;
    delete p13;

    return 0;
}

三、初始化与赋值的区别

const成员、引用成员等,只能初始化,不能赋值。

总结

C++ 对象初始化方式多样,核心是通过构造函数实现,根据场景选择:

到此这篇关于c++中类的对象初始化的实现示例的文章就介绍到这了,更多相关c++ 类对象初始化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:
阅读全文