网站上的弹框如何做网页,高端网站建设 骆,简述网站的四种常见结构,公司建设网站价格多少以下内容源于C语言中文网的学习与整理#xff0c;非原创#xff0c;如有侵权请告知删除。 一、对象数组
对象数组#xff0c;即数组的每个元素都是某个类的对象。
1、对象数组中的每个元素都需要用构造函数初始化#xff0c;具体哪些元素用哪些构造函数初始化#xff0c…以下内容源于C语言中文网的学习与整理非原创如有侵权请告知删除。 一、对象数组
对象数组即数组的每个元素都是某个类的对象。
1、对象数组中的每个元素都需要用构造函数初始化具体哪些元素用哪些构造函数初始化取决于定义数组时的写法。
请看下面的例子
#includeiostream
using namespace std;class CSample{
public:CSample(){ //构造函数 1coutConstructor 1 Calledendl;}CSample(int n){ //构造函数 2coutConstructor 2 Calledendl;}
};int main(){coutsteplendl;CSample arrayl[2]; //1,1//类似于CSample arrayl[0](),arrayl[1]() ? 有这种写法吗coutstep2endl;CSample array2[2] {4, 5};//2,2//类似于CSample arrayl[0](4),arrayl[1](5) ? 有这种写法吗coutstep3endl;CSample array3[2] {3};//2,1coutstep4endl;CSample* array4 new CSample[2];//1,1delete [] array4;return 0;
}
stepl
Constructor 1 Called
Constructor 1 Called
step2
Constructor 2 Called
Constructor 2 Called
step3
Constructor 2 Called
Constructor 1 Called
step4
Constructor 1 Called
Constructor 1 Called
step1的 array1 数组中的两个元素没有指明如何初始化那么默认调用无参构造函数初始化因此输出两行 Constructor 1 Called。
step2的 array2 数组进行了初始化初始化列表 {4, 5} 可以看作用来初始化两个数组元素的参数所以 array2[0] 以 4 为参数调用构造函数 2 进行初始化array2[1] 以 5 为参数调用构造函数 2 进行初始化。这导致输出两行 Constructor 2 Called。
step3的 array3 指出了 array3[0] 的初始化方式没有指出 array3[1] 的初始化方式因此分别用构造函数 2 和构造函数 1 进行初始化。
step4动态分配了一个 CSample 数组其中有两个元素没有指出和参数有关的信息因此这两个元素都用无参构造函数初始化。
2、在构造函数有多个参数时数组的初始化列表中要显式地包含对构造函数的调用。
例如下面的程序
class CTest{
public:CTest(int n){ } //构造函数(1)CTest(int n, int m){ } //构造函数(2)CTest(){ } //构造函数(3)
};
int main(){//三个元素分别用构造函数(1)、(2)、(3) 初始化CTest arrayl[3] { 1, CTest(1,2) };//像{1, (1,2)}这样行不行呢//三个元素分别用构造函数(2)、(2)、(1)初始化CTest array2[3] { CTest(2,3), CTest(1,2), 1};//两个元素指向的对象分别用构造函数(1)、(2)初始化CTest* pArray[3] { new CTest(4), new CTest(1,2) }; //第13行return 0;
}
上面程序中比较容易令初学者困惑的是第 13 行。
pArray 数组是一个指针数组其元素不是 CTest 类的对象而是 CTest 类的指针。第 13 行对 pArray[0] 和 pArray[1] 进行了初始化把它们初始化为指向动态分配的 CTest 对象的指针而这两个动态分配出来的 CTest 对象又分别是用构造函数1和构造函数2初始化的。pArray[2] 没有初始化其值是随机的不知道指向哪里。
第 13 行生成了两个 CTest 对象而不是三个所以也只调用了两次 CTest 类的构造函数。 二、成员对象与封闭类
1、一些概念理解
如果一个类的成员变量是另一个类的对象则称该成员变量为“成员对象”而包含成员对象的类叫封闭类enclosed class。
2、封闭类的对象的初始化
创建封闭类的对象时它包含的成员对象也需要被创建这就会引发成员对象构造函数的调用。成员对象的构造函数可能有很多个即函数重载那如何让编译器知道成员对象到底是用哪个构造函数进行初始化这就需要借助封闭类构造函数的初始化列表。
一个简单的示例如下
#include iostream
using namespace std;//1、轮胎类
class Tyre{
public:Tyre(int radius, int width);//轮胎类构造函数的声明void show() const;
private:int m_radius; //半径int m_width; //宽度
};
//轮胎类构造函数的定义
Tyre::Tyre(int radius, int width) : m_radius(radius), m_width(width){ }
void Tyre::show() const {cout 轮毂半径 this-m_radius 吋 endl;cout 轮胎宽度 this-m_width mm endl;
}//2、引擎类
class Engine{
public:Engine(float displacement 2.0);//引擎类构造函数的声明void show() const;
private:float m_displacement;
};
//引擎类构造函数的定义
Engine::Engine(float displacement) : m_displacement(displacement) {}
void Engine::show() const {cout 排量 this-m_displacement L endl;
}//3、汽车类
class Car{
public:Car(int price, int radius, int width);//汽车类构造函数的声明void show() const;
private:int m_price; //价格Tyre m_tyre;Engine m_engine;
};
//汽车类构造函数的定义
Car::Car(int price, int radius, int width): m_price(price), m_tyre(radius, width){ };//指明m_tyre对象的初始化方式
void Car::show() const {cout 价格 this-m_price endl;this-m_tyre.show();this-m_engine.show();
}int main()
{Car car(200000, 19, 245);//第51行car.show();return 0;
}
价格200000
轮毂直径19吋
轮胎宽度245mm
排量2L
封闭类构造函数的初始化列表其写法如下
封闭类的类名::封闭类的构造函数名(参数表): 成员变量名(参数表),…,成员对象名(参数表)
{//TODO:
}
对于封闭类Car它有一个成员变量m_price两个成员对象m_tyre 和 m_engine。而且编译器知道第 51 行的 car 这个对象是用 Car(int price, int radius, int width) 这个构造函数进行初始化的。
1对于基本类型的成员变量比如成员变量 m_price 是 int 类型其“参数表”中只有一个值就是初始值在调用构造函数时会把这个初始值直接赋给成员变量。比如Car类构造函数的初始化列表中将初始值 price 赋值给成员变量 m_price。
2对于成员对象“参数表”中存放的是构造函数的参数它可能只有一个值也可能有多个值它指明了该成员对象如何被初始化。比如Car类构造函数的初始化列表中m_tyre(radius, width)告诉编译器应该以 radius 和 width 作为参数传入构造函数 Tyre(int radius, int width) 中来初始化m_tyre这个对象。
3这里没有说明 m_engine 该如何处理此时编译器就认为 m_engine 应该用 Engine 类的无参构造函数初始化而 Engine 类确实有一个无参构造函数设置了固定参数而视为无参。
总之生成封闭类对象的语句一定要让编译器能够弄明白其成员对象是如何初始化的否则就会编译错误。在上面的程序中如果 Car 类的构造函数没有初始化列表那么第 51 行就会编译出错因为编译器不知道该如何初始化 car.m_tyre 对象因为 Tyre 类没有无参构造函数而编译器又找不到用来初始化 car.m_tyre 对象的参数。
3、成员对象的消亡
封闭类对象生成时先执行所有成员对象的构造函数然后才执行封闭类自己的构造函数。成员对象构造函数的执行次序和成员对象在类定义中的次序一致与它们在构造函数初始化列表中出现的次序无关。
当封闭类对象消亡时先执行封闭类的析构函数然后再执行成员对象的析构函数成员对象析构函数的执行次序和构造函数的执行次序相反即先构造的后析构这是 C 处理此类次序问题的一般规律。
#includeiostream
using namespace std;class Tyre {
public:Tyre() { cout Tyre constructor endl; }~Tyre() { cout Tyre destructor endl; }
};class Engine {
public:Engine() { cout Engine constructor endl; }~Engine() { cout Engine destructor endl; }
};class Car {
private:Engine engine;Tyre tyre;
public:Car() { cout Car constructor endl; }~Car() { cout Car destructor endl; }
};int main() {Car car;return 0;
}
Engine constructor
Tyre constructor
Car constructor
Car destructor
Tyre destructor
Engine destructor