Author:gnuhpc
WebSite:blog.csdn.net/gnuhpc
1.在子类构造时完成父类(没有默认构造函数)的初始化参数传入:
#include <iostream>
class Foo
{
public:
Foo( int x )
{
std::cout << "Foo's constructor "
<< "called with "
<< x
<< std::endl;
}
};
class Bar : public Foo
{
public:
Bar() : Foo( 10 ) // construct the Foo part of Bar
{
std::cout << "Bar's constructor" << std::endl;
}
};
int main()
{
Bar stool;
}
2.初始化const成员和reference成员
#include <iostream>
using namespace std;
class const_field
{
public:
const_field(int ii) : _constant( 1 ),ref( i ) { i=ii; }
int geti(){return i;}
int getref(){return ref;}
private:
const int _constant;
int &ref;
int i;
};
int main()
{
const_field cos(100);
cout << cos.geti() <<" " << cos.getref()<<endl;
}
注:初始化列表在构造函数函数体运行之前完成,在构造函数函数体运行中,数据成员的设置是赋值,而不是初始化。初始化阶段可以是显式或隐式的,这要取决于类成员的类型,对于built-in成员其实都一样,但是对于类成员,是否存在成员初始化表则有所不同:若不存在则是隐式初始化,按照声明的顺序依次调用所有类成员函数所属基类的默认构造函数(见后边的练习),在函数体内有赋值动作调用赋值构造函数。若存在则属于显式初始化,类成员使用复制构造函数完成初始化,这也就是我们有时会说在初始化列表中初始化开销会小些的原因(因为若在函数体内再赋值,那么类成员函数的默认构造函数执行所做的工作都是无用功),例如:
Account(){
_name = “”:
_balance=0.0;
}
这里面的string型的_name在赋值前已经被初始化阶段隐式初始为空串(调用了string的默认构造函数),所以在函数体中的赋值是完全没有意义的。
总之,建议使用初始化列表(注意是按照成员声明顺序,而不是列表顺序)来做对象创建时初始化工作。
初始化顺序为:
- 基类
- 成员数据成员(初始化列表)
- 构造函数函数体
附:练习
#include <iostream>
using namespace std;
class Test
{
public:
Test()
{
ctor_count++;
cout<<"ctor "<<ctor_count<<endl;
}
Test(const Test & r)
{
ctor_count++;
cout<<"copy ctor "<<ctor_count<<endl;
}
Test & operator= (const Test& r)
{
ctor_count++;
cout<<"assignment op "<<ctor_count<<endl;
return *this;
}
private:
static int ctor_count; //only a declaration
};
int Test::ctor_count=0; // definition + initialization
class Task
{
private:
int pid;
Test name; // type changed from string to Test
public:
Task (int num, const Test & n) {pid=num; name=n;}
};
int main(void)
{
Test t;
Task task(1, t);
return 0;
}
运行结果:
[root@localhost ~]# ./a.out
ctor 1
ctor 2
assignment op 3
解释:static int是为了更好的说明问题,不要被这个类型所迷惑。第一行表示程序在构造t。第二行表示默认初始化时调用默认构造函数,第三行是构造task时的赋值。
将程序的初始化修改:
Task (int num, const Test & n):pid(num),name(n) {}
运行结果是:
ctor 1
copy ctor 2
下边的这个程序也可以说明问题,如果还不理解上例的话:
#include <iostream>
using namespace std;
class Bar
{
public:
Bar();
Bar(int x);
Bar & operator=(const Bar& bar)
{
cout <<"Assignment Bar constructed." <<endl;
}
Bar(const Bar &bar)
{
cout <<"Copy Bar constructed." <<endl;
}
private:
int x;
};
Bar::Bar()
{
std::cout << "Bar default-constructed." << std::endl;
}
Bar::Bar(int x) : x(x)
{
std::cout << "Bar constructed." << std::endl;
}
class Foo
{
public:
Foo(Bar bar);
private:
Bar bar;
};
Foo::Foo(Bar bar)
{
this->bar = bar;
}
//Foo::Foo(Bar bar):bar(bar){}
int main()
{
Foo foo(Bar(3));
return 0;
}
分享到:
相关推荐
构造函数初始化列表是C++中一个非常重要的特性,它允许程序员在对象创建时直接对类中的成员进行初始化,而不是先分配内存再赋值,这在效率和安全性上都有显著优势。 #### 构造函数初始化列表的作用与语法 构造函数...
C++中的全局变量初始化是一个重要的话题,涉及到程序的正确性和可预测性。全局变量,即具有静态存储期的变量,其生命周期始于程序开始,终于程序结束。本文将深入探讨全局变量初始化的时机、方式以及一些处理特殊...
在C++编程中,成员初始化列表是一个非常重要的概念,尤其是在类的设计和实现过程中。本文将详细解释成员初始化列表的概念、用途以及它与传统构造函数内初始化的区别,并通过具体示例来阐述其在特定场景下的应用。 #...
C++类的成员初始化列表是构造函数中一种特殊的形式,用于在对象实例化时直接对类的成员变量进行初始化。这种列表在特定情况下是必要的,因为它可以提高代码的效率并确保正确的初始化顺序。 首先,成员初始化列表在...
C++中,全局变量只能声明、初始化,而不能赋值 也就是说,下面这样是不被允许的: #include using namespace std; int a; a = 2; int main() { return 0; } 错误提示是: C++ requires a type specifier for all...
C++使用初始化列表的方式来初始化字段的方法 C++语言中,初始化列表是一种常用的初始化对象成员的方法。今天,我们来探讨C++使用初始化列表的方式来初始化字段的方法。 首先,让我们了解什么是初始化列表。初始化...
Although it is not as big a step as C++11, it contains a large number of small and valuable language and library features, which again will change the way we program in C++. This applies to both ...
C++为类中提供类成员的初始化列表 类对象的构造 顺序是这样的:1.分配内存,调用构造函数 时,隐式/显示的初始化各数据 成员2.进入构造函数后在构造函数中执行一般计算 使用初始化列表有两个原因: 1.必须这样做:...
C++ 类对像构造时,需要对类成员变量完成初始化赋值操作。使用初始化列表完成这步操作在性能上有益处。什么好处呢?摆道理显得不够彻底。看书不如做实验。让我们结合执行过程来查看。考虑如下示例代码: ...
1.只能在构造函数初始化列表初始化的成员变量的类型? a.const成员变量 b.引用类型的成员变量 c.static不能在初始化列表中进行初始化 d.类成员变量中有自定义类型的变量最好在初始化列表中进行初始化 2.初始...
《C++ Templates: The Complete Guide》是一本深入探讨C++模板技术的专业书籍,旨在为读者提供全面、详尽的模板知识。模板是C++语言中一个强大的特性,它允许程序员编写泛型代码,以实现代码复用和高效编程。下面...
MyClass(int y) : member(y) {} // 使用成员初始化列表初始化成员类 }; ``` #### 三、成员初始化列表的过程 1. **成员变量按声明顺序初始化**:成员初始化列表中的项目顺序是由类中的成员声明顺序决定的,而...
在本文中,我们将聚焦三个关键特性:`decltype`、类内初始化以及列表初始化返回值。 首先,`decltype`是一个类型推断关键字,它允许程序员根据表达式的类型来声明一个新的类型。其基本规则如下: 1. 如果表达式`e`...
在C++11中,结构体或类的数据成员在申明时可以直接赋予一个默认值,初始化的方式有两种,一是使用等号“=”,二是使用大括号列表初始化的方式。注意,使用参考如下代码: class C { private: int a=7; //C++11 ...
由于 `struct` 在C++中等同于类,但不支持构造函数,所以我们必须使用成员初始化列表。例如,对于 `PhotoInfo` 结构体,其初始化如下: ```c++ PHOTOINFO_t myPhoto = { NULL_STRING, NULL_STRING, // ... 其他...
原因:C++可以定义引用类型的成员变量,引用类型的成员变量必须在构造函数的初始化列表中进行初始化。对于类成员是const修饰,或是引用类型的情况,是不允许赋值操作的,(显然嘛,const就是防止被错误赋值的,引用...
(1)初始化顺序表L (2)从标准输入(键盘)逐个数据输入a,b,c,d,e元素 ,建立顺序表 (3)输出顺序表L (4)输出顺序表L的长度 (5)判断顺序表L是否为空 (6)输出顺序表L的第3个元素 (7)输出元素a的位置...
还有以下两个成员函数:一个用于初始化学生姓名、学号、性别和年龄的构造函数,一个用于输出学生信息的函数。编写一个主函数。声明一个学学生对象。然后调用成员函数在屏幕输出学生信息。 编程环境:vs2010,语言:...
Beyond the C++ Standard Library : An Introduction to Boost (Chinese)