C++拾遗--构造函数(一)默认构造

news/2024/5/18 22:11:54 标签: 构造函数, 初始值列表, 初始化, 赋值, const

                    C++拾遗--构造函数(一)默认构造

前言

    对一个类而言,构造函数恐怕是最重要的一个成员函数了。关于构造函数的细节繁多,并且随着新标准的提出,构造函数有了新的特性。本文来集中探讨下构造函数的那些鲜为人知的一面。

构造函数

    构造函数的作用众所周知:在类的对象被创建时,控制对象的初始化赋值

构造函数的一般形式:

                       类名(arg_list);

其中arg_list是用逗号隔开的参数列表。

特点:无返回值类型,且不可加const限制。

默认构造函数

需要特别指出,无参的构造函数是默认的,有参但都有默认参数的构造函数也是默认构造。

举例证明:

#include <iostream>
using namespace std;

class MyClass
{
protected:
	int a = 0;
	int b{1};
public:
	MyClass(int a = 0, int b = 0):a(a), b(b)   //有默认实参的构造方法就是默认构造
	{
		cout << "MyClass(int a = 0, int b = 0)" << endl;
	}

	int getA()const
	{
		return a;
	}
	int getB()const
	{
		return b;
	}
};
int main()
{
	MyClass my;   //调用默认构造
	cout << "a = " << my.getA() << ends << "b = " << my.getB() << endl;
	cin.get();
	return 0;
}
运行



从运行结果,即可验证结论。有参但都有默认参数的构造函数也是默认构造,这一点恐怕是很多人都容易忽略的、

默认构造初始化类的数据成员的规则:

  1. 如果存在类内的初始值,用它来初始化成员。
  2. 否则,默认初始化。(这个规则虽是标准,但大多数编译器还做不到)

几个概念

1.类内初始值。
在上例代码中,int a = 0; int b{1};这种形式就是类内初始值。后面会说明何时使用类内初始值。

2.默认初始化
内置类型,如int,double类型等。int->0,double->0.0。就是默认初始化
类类型,使用该类的默认构造初始化,就是默认初始化

默认构造并不是总是存在的,若有另一个构造函数(非默认构造)存在,则编译器并不会提供一个无参的默认构造。新标准提出了一种方式:如 MyClass() = default; 关键字 default 的这种使用,表明要求编译器生成一个默认的构造函数

构造函数 MyClass(int a = 0, int b = 0):a(a), b(b){...}   其中 a(a), b(b)就是初始值列表

4.什么是初始化?什么是赋值
对象在内存中创建(有了内存实体),第一次有的值,叫做初始化。把原先的值覆盖掉,叫做赋值

一般情况下,构造函数初始值列表中完成初始化,在函数体中完成赋值
这个结论并不好证明,但还是有办法的,办法就是借助:const类型和引用类型。如下代码:
#include <iostream>
using namespace std;

class MyClass
{
protected:
	int a = 0;
	const int ca = 0;
	int& ra;
public:
	MyClass(int a) :a(a), ca(a), ra(this->a){}
	int getA()const
	{
		return a;
	}
	void printCa()const
	{
		cout << "ca = " << ca << endl;
	}
	void printRa()const
	{
		cout << "ra = " << ra << endl;
	}
};
int main()
{
	MyClass my(1);
	cout << my.getA() << endl;
	my.printCa();
	my.printRa();
	cin.get();
	return 0;
}
运行


const类型和引用类型,在创建时,必须进行初始化。若是把 ca = a; ra = this->a; 移到构造函数体内部,则无法通过编译。也就是说,一旦进入构造函数体,初始化就已经完成了。

需要指出,初始值列表的顺序并不代表着实际初始变量的顺序,而成员的声明顺序才是。





本专栏目录
  • C++拾遗 目录
所有内容的目录
  • CCPP Blog 目录




http://www.niftyadmin.cn/n/1802122.html

相关文章

C++拾遗--构造函数(二)拷贝构造

C拾遗--构造函数(二)拷贝构造 前言 在构造函数(一)中讨论的是默认构造函数的一些应用。这里我们来探讨下其它的一些有名构造函数&#xff0c;及其它们的应用场景。 实例 #include <iostream> using namespace std;class Complex { protected:int real 0;int imag 0; …

C++拾遗--函数模板

C拾遗--函数模板 前言 泛型的核心思想是数据与算法分离。函数模板是泛型编程的基础。 函数模板 函数模板以 template<arg_list> 开头&#xff0c;arg_list是泛型参数的列表。 1.模板的泛型参数个数确定 实例一 下面是一个加法函数模板&#xff0c;在实例化时&#…

C++拾遗--name_cast 显式类型转换

C拾遗--name_cast 显式类型转换 前言 C中提供了四种显式的类型转换方法&#xff1a;static_cast,const_cast,reinterpret_cast,dynamic_cast.下面分别看下它们的使用场景。 显式类型转换 1.staitc_cast 这是最常用的&#xff0c;一般都能使用&#xff0c;除了不能转换掉底层…

C++拾遗--模板元编程

C拾遗--模板元编程 前言 模板元是用于递归加速的&#xff0c;把运行期的函数调用变到编译期进行代码展开&#xff0c;类似于内联函数。下面看一个实例&#xff1a;斐波那契数列第n项求解。 模板元编程 #include <iostream> #include <ctime> using namespace std…

C++拾遗--智能指针

C拾遗--智能指针 前言 内存泄露是常见的问题&#xff0c;新标准中的智能指针从根本上解决了这个问题。所谓的智能指针&#xff0c;其智能性体现在&#xff1a;当没有对象使用某块动态分配的内存时&#xff0c;那就自动释放这片内存。 智能指针 下面这段程序可耗尽内存&#…

C++拾遗--malloc free与new delete的同与不同

C拾遗--malloc free与new delete的同与不同 前言 在C中我们常使用malloc和free来动态分配与释放内存&#xff0c;在C中对应的是new和delete。这里我们来探讨下他们的同与不同。 正文 1.内置类型 对相同的代码进行调试&#xff0c;查看内存 #include <iostream> using…

C++拾遗--new delete 重载

C拾遗--new delete 重载 前言new和delete是操作动态内存的一对操作。对它们重载可以对内存管理进行有效的定制。 正文 1.局部重载 特别针对某一类型&#xff0c;对new和delete进行重载&#xff0c;可以对该类型对象的动态创建实行监控。如下代码&#xff1a; 代码一#include &l…

C++拾遗--定位new表达式

C拾遗--定位new表达式 前言 new表达式&#xff0c;默认下把内存开辟到堆区。使用定位new表达式&#xff0c;可以在指定地址区域(栈区、堆区、静态区)构造对象&#xff0c;这好比是把内存开辟到指定区域。 正文 定位new表达式的常见形式 new(address) type;new(address) type…