栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【日常总结】c++ 类默认成员函数以及成员初始化探索

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【日常总结】c++ 类默认成员函数以及成员初始化探索

c++ 类默认成员函数以及成员初始化探索 1、类的默认成员函数

构造函数、析构函数、拷贝构造函数、赋值运算符重载、&操作符重载、const &重载 –参考链接

例子:

定义一个空类

class Empty
{
}

一个空的class在C++编译器处理过后就不再为空,编译器会自动地为我们声明一些成员函数,代码如下:

class Empty
{
public:
Empty(); // 缺省构造函数
Empty( constEmpty& ); // 拷贝构造函数
~Empty(); // 析构函数
Empty&operator=( const Empty& ); // 赋值运算符
Empty*operator&(); // 取址运算符
const Empty*operator&() const; // 取址运算符const
};
2、成员初始化

利用默认构造函数初始化成员变量

#include

class A
{

public:
	A() = default;
	void print() {
		std::cout << "val_a: " << val_a << "  &val_a: " << &val_a << std::endl;
		std::cout << "val_b: " << val_b << "  &val_b: " << &val_b << std::endl;
		std::cout << "val_c: " << val_c << "  &val_c: " << &val_c << std::endl;
	}
	static int val_static;
private:
	int val_a;
	int val_b;
	int val_c ;
};

int A::val_static = 1;  // 若不赋值,用默认的值,编译器,编译直接不给打印val_static的值

int main()
{
	A a;
	a.print();
	std::cout << "val_static: " << A::val_static << "  &val_static: " <<  &A::val_static << std::endl;  // 打印val_static的值
}
  • 利用vs debug模式中成员变量值没有初始化,其结果为:
val_a: -858993460  &val_a: 00DEFC30
val_b: -858993460  &val_b: 00DEFC34
val_c: -858993460  &val_c: 00DEFC38
val_static: 1  &val_static: 00CA6000

从上面结果可以看出,成员函数没有给初始值,值都为-858993460(0xcccccccc),且都有分配内存。

  • 利用vs debug模式中成员变量值没有初始化,其结果为:
val_a: 0  &val_a: 0136FA68
val_b: 1988144199  &val_b: 0136FA6C
val_c: 17113088  &val_c: 0136FA70
val_static: 1  &val_static: 005B4018

从上面的结果可以看出,成员函数没有给初始值,值是随机给的,且都分配内存。

3、初始化成员的先后顺序

代码:(参考)

#include
using namespace std;
class A
{
	int a;
	int b;
public:
	A() :b(0), a(b + 2){	}
	void print()
	{
		cout << "a = " << a << " ,b = " << b << endl;
	}
};
int main()
{
	A a;
	a.print();
	return 0;
}

运行结果:

a = 7476729 ,b = 0

从结果可值,类中成员变量初始化的先后次序与变量在类中被定义的先后次序有关,与构造函数中被初始化的先后顺序无关。

4、构造函数初始化调用顺序

参考

#include 
using namespace std;
class OBJ1{
public:
OBJ1(){ cout<<"OBJ1n"; }
};
class OBJ2{
public:
OBJ2(){ cout<<"OBJ2n";}
}
class Base1{
public:
Base1(){ cout<<"Base1n";}
}
class Base2{
public:
Base2(){ cout <<"Base2n"; }
};
class Base3{
public:
Base3(){ cout <<"Base3n"; }
};
class Base4{
public:
Base4(){ cout <<"Base4n"; }
};
class Derived :public Base1, virtual public Base2,public Base3, virtual public Base4//继承顺序{
public:
Derived() :Base4(), Base3(), Base2(),Base1(), obj2(), obj1(){//初始化列表
cout <<"Derived ok.n";
}
protected:
OBJ1 obj1;//声明顺序
OBJ2 obj2;
};

int main()
{
Derived aa;//初始化
cout <<"This is ok.n";
return 0;
}

结果:

Base2 //虚拟基类按照被继承顺序初始化
Base4 //虚拟基类按照被继承的顺序
Base1 //非虚拟基类按照被继承的顺序初始化
Base3 //非虚拟基类按照被继承的顺序
OBJ1 //成员函数按照声明的顺序初始化
OBJ2 //成员函数按照声明的顺序
Derived ok.
This is ok.

由上可知,C++构造函数初始化按下列顺序被调用:

  • 首先,任何虚拟基类的构造函数按照它们被继承的顺序构造;
  • 其次,任何非虚拟基类的构造函数按照它们被继承的顺序构造;
  • 最后,任何成员对象的构造函数按照它们声明的顺序调用;
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/833043.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号