弹窗广告最多的网站,php可以做移动端网站,做网站需要了解什么,宁波网站设计公司哪个好目录
构造函数
构造函数的基本使用
构造函数也支持函数重载
构造函数也支持函数参数默认值
构造初始化列表
拷贝构造函数
浅拷贝和深拷贝
析构函数 总结
练习一下ヽ(#xffe3;▽#xffe3;)#xff89; 构造函数
构造函数的基本使用 构造函数是一种特殊的成…目录
构造函数
构造函数的基本使用
构造函数也支持函数重载
构造函数也支持函数参数默认值
构造初始化列表
拷贝构造函数
浅拷贝和深拷贝
析构函数 总结
练习一下ヽ(▽) 构造函数
构造函数的基本使用 构造函数是一种特殊的成员函数用于创建对象时初始化写法上有以下要求 ● 函数名称必须与类名完全一样。 ● 构造函数不写返回值 ● 如果程序员不手动编写构造函数编译器就会自动添加一个默认无参数的构造函数。 ● 手动添加构造函数后编译器就不会自动添加默认无参构造函数。 class Car
{
private://权限最私有的权限string brand; // 品牌string modle; // 型号int weight; // 重量
public: // 权限最开放的权限Car(string b,string m,int w) //手动添加的构造函数{brandb;modlem;weightw;}string get_brand() //外部函数接口{return brand;}string get_modle(){return modle;}int get_weight(){return weight;}
};
int main()
{Car *myCar new Car; // 创建堆内存对象//cout Car.brand endl; //错误brand是私有成员 不能外部访问cont Car.get_brand endl; //可以使用预留的接口访问
}
构造函数也支持函数重载
class Car
{
private://权限最私有的权限string brand; // 品牌string modle; // 型号int weight; // 重量
public: // 权限最开放的权限Car(string b,string m,int w) // 有参构造函数{brandb;modlem;weightw}Car() // 无参构造函数{brandxiaomi;modlesu7;weight1500}string get_brand() // 外部函数接口{return brand;}string get_modle(){return modle;}int get_weight(){return weight;}
};
int main()
{Car *myCar new Car; // 调用无参构造函数Car *myCar2 new Car(HuaWei,问界,2000); // 此时调用有参构造函数}
构造函数也支持函数参数默认值
从第一个设置默认值的变量开始在其变量之后的所有参数都要加默认值在他之前的变量可以不加默认值。
class Car
{
private://权限最私有的权限string brand; // 品牌string modle; // 型号int weight; // 重量
public: // 权限最开放的权限Car(string bxiaomi,string msu7,int w1500) // 全缺省时不能和无参构造函数同时存在{brandb;modlem;weightw}// Car() // 无参构造函数// {// brandxiaomi;// modlesu7;// weight1500// }string get_brand() // 外部函数接口{return brand;}string get_modle(){return modle;}int get_weight(){return weight;}
};
int main()
{Car *myCar new Car; // 全缺省Car *myCar2 new Car(问界,M7,2000); // 此时调用有参构造函数}
构造初始化列表
当构造函数的局部变量与成员变量重名时可以使用构造初始列表的方式区分此外使用构造初始化列表还可以给被 const 修饰的成员变量赋值。
class Car
{
private://权限最私有的权限const string brand; // 品牌string modle; // 型号int weight; // 重量
public: // 权限最开放的权限Car(string b,string modle,int w):brand(b),modle(modle),weight(w){} // 用构造初始化列表的方式赋值string get_brand() // 外部函数接口{return brand;}string get_modle(){return modle;}int get_weight(){return weight;}
};
int main()
{Car *myCar new Car(问界,M7,2000); // 此时调用有参构造函数}
拷贝构造函数
C的拷贝构造函数是一种特殊的成员函数用于创建一个对象的副本。它的参数是一个对象的引用通过这个参数可以将一个对象的值复制给另一个对象。
拷贝构造函数通常在以下情况下被调用
1、当用一个对象初始化另一个对象时会调用拷贝构造函数。例如
class MyClass {
public:MyClass(const MyClass obj) {// 拷贝构造函数的实现}
};MyClass obj1;
MyClass obj2 obj1; // 调用拷贝构造函数2、当将一个对象作为函数参数传递给函数时会调用拷贝构造函数。例如
void func(MyClass obj) {// 函数体
}MyClass obj;
func(obj); // 调用拷贝构造函数3、当函数返回一个对象时会调用拷贝构造函数。例如
MyClass func() {MyClass obj;// 对 obj 进行初始化和操作return obj; // 调用拷贝构造函数
}需要注意的是默认情况下C会生成一个默认的拷贝构造函数该函数会将对象的所有成员变量进行一一拷贝。但如果类中存在指针或其他资源需要手动编写拷贝构造函数来处理这些资源的拷贝问题以防止浅拷贝带来的问题。 浅拷贝和深拷贝
C中的拷贝操作有浅拷贝和深拷贝两种方式。
浅拷贝是指拷贝对象时只是简单地将一个对象的数据成员的值复制给另一个对象的对应数据成员而不会复制指向动态分配内存的指针。这意味着两个指针将指向同一块内存当其中一个对象释放这块内存时另一个对象的指针将成为悬空指针。例如
class MyClass {
public:int* data;MyClass(const MyClass other) : data(other.data) {// 拷贝构造函数的实现}
};MyClass obj1;
obj1.data new int(5);MyClass obj2 obj1; // 浅拷贝delete obj1.data; // 释放内存
cout *obj2.data; // 可能会输出无效的值深拷贝是指拷贝对象时除了复制数据成员的值外还会为每个指针成员分配一块新的内存并将源对象的值复制到新的内存中以确保两个对象之间的指针成员指向不同的内存块。这样即使一个对象释放了内存另一个对象的指针仍然有效。例如
class MyClass {
public:int* data;MyClass(const MyClass other) : data(new int(*other.data)) {// 拷贝构造函数的实现}~MyClass() {delete data;}
};MyClass obj1;
obj1.data new int(5);MyClass obj2 obj1; // 深拷贝delete obj1.data; // 释放内存
cout *obj2.data; // 仍然可以正常输出析构函数
C中的析构函数是一种特殊的成员函数用于在对象的生命周期结束时执行清理操作。析构函数的名称与类的名称相同前面加上一个波浪号(~)作为前缀没有返回类型也没有参数。
析构函数在以下情况下被调用
当对象的作用域结束时例如当对象在函数中定义并在函数结束时销毁。当对象是另一个对象的成员并且该对象的析构函数被调用时。当使用delete关键字显式释放通过new关键字配分的内存时。
析构函数的主要目的是释放对象分配的资源例如动态分配的内存、打开的文件等。它可以通过在析构函数中使用delete关键字来释放内存或者通过关闭文件句柄等操作来释放资源。
以下是一个示例展示了一个类的析构函数的基本用法
class MyClass {
public:MyClass() {cout 构造函数被调用 endl;}~MyClass() {cout 析构函数被调用 endl;}
};int main() {MyClass obj; // 创建一个对象// 在此处执行其他操作return 0; // 对象的作用域结束析构函数被调用
}当对象的作用域结束时析构函数将被自动调用输出如下结果
构造函数被调用
析构函数被调用需要注意的是如果类中使用了动态分配的内存或其他资源在析构函数中应该对这些资源进行释放以避免内存泄漏或资源泄漏的问题。 总结 构造函数 析构函数 创建对象时手动调用 当对象销毁时自动调用 函数名称是类名 函数名称是~类名 构造函数可以重载 析构函数没有参数不能重载 用于创建对象时并初始化 用于销毁对象时释放资源 有返回值但是不写返回值是新创建的对象 没有返回值 练习一下ヽ(▽) 写一个Dog类要求有性别、年龄和品种三个属性属性值封装使用构造函数传参初始化。增加函数Dog* birth(const Dog d)在函数体内部判断d与当前狗对象的属性值当满足以下条件时返回新创建的狗对象 ● 两条狗的年龄2-5 ● 一公一母 新创建的狗对象的属性满足以下条件 ● 年龄1岁 ● 性别随意 ● 品种 ○ 如果父母的品种一样品种就是父母的品种 ○ 如果父母的品种不一样品种是父母品种的拼合自己制定拼合逻辑或者直接是父母的品种之一 如果两条狗不能生育返回NULL。 参考代码 #include iostream
#includestring.h
#includetime.h
using namespace std;class Dog
{
private:int sex; //0母 1公int age; //小于2或大于5不能生育char *varietynew char[20];public:Dog(int s,int a,char *v){if(s3) // 性别随机{sextime(NULL)%2;}else{sexs;}agea;strcpy(variety,v);}Dog* brith(const Dog D){if(sex ! D.sex){if( age 2 || age 5 || D.age 2 || D.age 5 ){return NULL;}Dog* NewDog new Dog(3,1,D.variety);return NewDog;}return NULL;}int get_sex(){return sex;}int get_age(){return age;}char *get_variety(){return variety;}};int main()
{int sex,age;char variety[20];while(1){cout 请输入狗A的 性别0:母 1:公 年龄 品种 endl;cin sex age variety;Dog dogA(sex,age,variety);cout 请输入狗B的 性别0:母 1:公 年龄 品种 endl;cin sex age variety;Dog dogB(sex,age,variety);Dog* NewDogdogB.brith(dogA);if(NewDogNULL){cout dogA和dogB无法生育 endl;continue;}cout 小狗的属性 endl;cout sex: NewDog-get_sex() endl;cout age: NewDog-get_age() endl;cout variety: NewDog-get_variety() endl;}return 0;
}