c++注意点(8)----构造
构造函数
-
名字和类名相同
-
没有返回值
-
构造函数是用来构造对象的,构造对象时候必定调用构造函数
-
不写构造函数,存在一个默认的构造函数,默认的构造函数是无参的,所以可以构造无参对象
-
默认的构造函数可以删掉,通过delete来删除
-
显式使用默认的构造函数,通过default做显示调用
-
通常情况下,是public属性
-
自己写了构造函数,默认的构造函数就不存在了
-
构造函数觉得了对象的长相(构造函数无参,对象无参)
-
构造函数:给数据成员初始化
-
构造函数也是函数,也可以重载,也可以缺省
结构体中也可以存在构造函数:
struct chen
{
int age;
char* name;
int num;
chen(char* pname,int page)
{age=page;name=pname;}
}
int main()
{
chen Chen={"chen",18}; //结构体中用了构造函数,创建结构体时,就需要按照构造函数形式来创建
cout<<Chen.name;
}
C++构造函数初始化列表
#include <iostream>
using namespace std;
class Student{
private:
char *m_name;
int m_age;
float m_score;
public:
Student(char *name, int age, float score);
void show();
};
//采用初始化列表
Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){}
本例所示,定义构造函数时并没有在函数体中对成员变量一一赋值,其函数体为空(当然也可以有其他语句),而是在函数首部与函数体之间添加了一个冒号:,后面紧跟m_name(name), m_age(age), m_score(score)语句,这个语句的意思相当于函数体内部的m_name = name; m_age = age; m_score = score;语句,也是赋值的意思。
初始化 const 成员变量
构造函数初始化列表还有一个很重要的作用,那就是初始化 const 成员变量。初始化 const 成员变量的唯一方法就是使用初始化列表。
class VLA{
private:
const int m_len;
int *m_arr;
public:
VLA(int len);
};
//必须使用初始化列表来初始化 m_len
VLA::VLA(int len): m_len(len){//若是 m_len = len这样写,就是错误的
m_arr = new int[len];
}
构造委托
也可以称为委托构造,允许一个构造函数调用另一个构造函数
为了避免无参构造时候数据未初始化,只能采用初始化参数列表调用
class chen
{
public:
// 委托构造函数:调用另一个构造函数
chen() : chen("") {} // 委托构造函数,委托给带参数的构造函数
// 目标构造函数:被委托的构造函数
chen(string name) : name(name) {} // 初始化成员变量name
private:
string name;
};
优势:
- 代码复用:避免在多个构造函数中重复相同的初始化逻辑
- 维护性:初始化逻辑集中在一个地方,修改时只需改一次
- 清晰性:明确指定了构造函数之间的依赖关系
注意:
- 委托构造函数不能同时直接初始化成员变量,只能委托给其他构造函数
- 可以形成委托链(A→B→C),但不能形成循环委托(A→B→A)
- 构造函数委托是 C++11 引入的特性,需要编译器支持 C++11 及以上标准
深浅拷贝问题
当类中包含「动态分配的资源」(如指针指向的堆内存、文件句柄、网络连接等)时,浅拷贝会导致问题。浅拷贝会导致同一段内存重复释放
#include<iostream>
#include<cstring>
using namespace std;
class Chen
{
public:
Chen() {};
Chen(const char* str)
{
int length = strlen(str) + 1;
name = new char[length];
strcpy_s(name, length, str);
}
~Chen()
{
if (name != nullptr)
{
delete[] name;
name = nullptr;
}
}
protected:
char* name;
};
int main()
{
{
Chen myself("chen");
Chen chen = myself;//浅拷贝问题
return 0;
}
}
讲解:
1. 对象创建与内存分配
Chen myself("chen"); // ① 创建对象myself
- 调用带参构造函数
Chen(const char* str) - 动态分配内存:
name = new char[length](假设地址为0x1000) - 将字符串 "chen" 复制到
0x1000地址
2.浅拷贝发生
Chen chen = myself; // ② 浅拷贝(默认拷贝构造函数)
C++ 会自动生成默认拷贝构造函数,其行为是浅拷贝 :
- 仅将
myself.name的值(0x1000)直接复制给chen.name - 此时
myself.name和chen.name指向同一块内存(0x1000)
3. 析构函数导致重复释放
当程序执行到 main 函数的 } 时,局部对象会按创建顺序的相反顺序销毁
总结:当类中包含「动态分配的资源」(如指针指向的堆内存、文件句柄、网络连接等)时,浅拷贝会导致问题。
解决办法就是自己写拷贝函数。
更多推荐


所有评论(0)