C++基础:缺省构造函数

缺省构造函数,又称默认构造函数,是C++以及其他的一些面向对象的程序设计语言中,对象的不需要参数即可调用的构造函数。下面将针对缺省构造函数的定义、使用、以及注意问题等方面简要探讨。

1、缺省构造函数是怎样的形式?是如何定义的?

在C++的一个类中,如果构造函数没有参数,或者构造函数的所有参数都有默认值,就可以称其为缺省构造函数。一个类中,只能有一个缺省构造函数

  • 对于如下代码:构造函数MyClass()没有参数,就是MyClass的缺省(默认)构造函数。


class MyClass
{
public:
MyClass(){
value = 1;
cout<<"无参默认构造函数调用并初始化value:"<<value<<endl;
};
private:
int value;
};

  • 而对于如下代码:构造函数Myclass(int  i =
    10)的所有参数(此处只有一个参数i)都有默认值,这样的形式,也是MyClass的缺省(默认)构造函数。


class MyClass
{
public:
MyClass(int i = 10){
value = i;
cout<<"参数都有默认值的默认构造函数调用并初始化value:"<<value<<endl;
};
private:
int value;
};

  • 要注意,一个类中只能有一个缺省构造函数。如果将以上的两个构造函数均加入类中,形如以下代码,就会有问题。


class MyClass
{
public:
MyClass(){
value = 1;
cout<<"无参默认构造函数调用并初始化value:"<<value<<endl;
};
MyClass(int i = 10){
value = i;
cout<<"参数都有默认值的默认构造函数调用并初始化value:"<<value<<endl;
};
private:
int value;
};

此时当建立MyClass
mc这样的对象的时候,就会报错:

2、缺省构造函数在何时被调用?

缺省构造函数的调用主要包括如下的几种情况:

  • 对象被定义时无参数,形如:MyClass mc;

  • 动态分配对象时无参数列表,形如:MyClass *mcptr = new MyClass; 或 MyClass *mcptr
    = new MyClass();

  • 使用静态分配的数组,数组元素为某个类的对象,形如: MyClass mcArrayStatic[5];

  • 使用动态分配的数组,数组元素为某个类的对象,形如:MyClass *mcArrayDynamic = new
    MyClass[6];

  • 使用标准库的容器(如vector),容器的元素类型是某个类的对象,形如:vector<MyClass>
    vmc(7);

  • 在派生类的构造函数中未显示调用基类的构造函数,此时基类的缺省构造函数会被调用

下面通过一段代码加以演示:


#include<iostream>
#include<vector>
using namespace std;

class MyClass
{
public:
MyClass(){
value = 1;
cout<<"无参默认构造函数调用并初始化value:"<<value<<endl;
};
/*MyClass(int i = 10){
value = i;
cout<<"参数都有默认值的默认构造函数调用并初始化value:"<<value<<endl;
};*/
private:
int value;
};

class MyClassChild:public MyClass
{
public:
MyClassChild(){
cout<<"派生类构造函数调用"<<endl;
}
};

class MyClass2
{
public:
MyClass2(){
cout<<"Myclass2构造函数调用"<<endl;
}
private:
MyClass myc;
};

//用于对缺省构造函数调用情况的演示测试,在main()函数直接调用即可
void test_myclass()
{
cout<<"对于默认构造函数调用的测试:"<<endl;
cout<<"\n未显示调用构造函数:"<<endl;
MyClass mc;
cout<<"\n显示调用构造函数:"<<endl;
MyClass *mcptr = new MyClass;
//或MyClass *mcptr = new MyClass();
cout<<"\n静态分配数组:"<<endl;
MyClass mcArrayStatic[5];
cout<<"\n动态分配数组:"<<endl;
MyClass *mcArrayDynamic = new MyClass[6];
cout<<"\n使用标准库容器:"<<endl;
vector<MyClass> vmc(7);//最大容量为7
cout<<"\n创建派生类:"<<endl;
MyClassChild mcc;
cout<<"\n包含别的类成员的类的创建:"<<endl;
MyClass2 mc2;
}

在main()函数调用test_myclass(),得到如下运行结果:

    3、注意事项:

(1)对于你所创建的类(如此处的MyClass),如果没有为该类提供任何构造函数,那么编译器会自动生成一个默认的无参数的构造函数,但该函数体为空,不进行任何工作;然而,只要你为你的类定义了构造函数,无论是默认的构造函数形式,还是非默认构造函数的形式,哪怕只有一个,编译器都不会再生成默认的构造函数。

举例言之,对于以上的类MyClass(),我去掉所有的构造函数,在运行下面的test_myclass(),依然可以运行,这是因为此时编译器为我的类生成了默认的构造函数,只是在其中未进行任何操作:

class MyClass
{

private:
int value;
};

(2)在需要调用默认构造函数的情况下,如果并不存在默认构造函数,就会出错。

比如,我定义了非默认构造函数形式的构造函数,此时编译器并不会帮我生成默认的构造函数,若运行test_myclass(),在需要调用默认构造函数的情况下,就会出错。


class MyClass
{
public:
/*MyClass(){
value = 1;
cout<<"无参默认构造函数调用并初始化value:"<<value<<endl;
};*/
MyClass(int i ){//没有默认值,就不是默认构造函数
value = i;
cout<<"参数都有默认值的默认构造函数调用并初始化value:"<<value<<endl;
};
private:
int value;
};

(3)并非所有的类都存在默认构造函数,前面已经说过,如果现实的定义了非默认构造函数,则编译器就不会自动生成默认构造函数,也就不存在默认构造函数,这是常见的错误,要注意。

(4)如果某派生类的基类没有缺省构造函数,那么编译器也不会为该类隐式地定义缺省构造函数。因为该类即使隐式地定义缺省构造函数,也无法初始化其基类。

(5)如果类的基类的缺省构造函数为私有,那么编译器会为该类隐式地定义缺省构造函数,但编译报错“cannot access private
member declared in class 基类名字”。

时间: 2024-10-01 02:55:52

C++基础:缺省构造函数的相关文章

为什么 没有缺省构造函数的类类型成员 必需要在初始化列表 里初始化 ?

名词解释 1.缺省构造函数:类的构造函数无参或参数默认值统称为缺省构造函数. 2.初始化列表:与其它函数不同,构造函数除了有名字,参数列表和函数体外还可以有初始化列表.列表以冒号开始后跟以逗号隔开的初始化字段.类成员是在构造函数的初始化列表创建好的,在创建类成员的同时,给成员变量一个初始化值. 在解释原因之前,需要了解构造函数是如何执行的 构造函数的执行过程 首先,构造函数的执行分为三步.先创建函数的形参(如果没有形参这步可以省略),然后执行初始化列表(即使没有初试化列表),最后执行函数体的内容

慎用缺省构造函数的一种场景

本文通过示例来谈谈慎用缺省构造函数的一种设计场景.--以JAVA为例展开讨论. 为了便于讨论,我们假定需要建模一个Student,包括姓名和出生地两个属性.我们看到不少下面的代码: public class Student { private String name = null; private String birthPlace = null; public Student() { } public void setName(String name) { this.name = name;

[转载]关于隐式提供缺省构造函数的一个误区

很多C++的教材中都讲:“如果一个定义一个类,并且不提供任何构造函数的话,那么编译器将会隐式的提供一个缺省构造函数”. 以下节录ISO C++ 99的文档的原文: The default constructor (12.1), copy constructor and copy assignment operator (12.8), and destructor (12.4) are special member functions. The implementation will implic

More Effective C++----(4)避免无用的缺省构造函数 &amp; (5)谨慎定义类型转换函数

Item M4:避免无用的缺省构造函数 缺省构造函数(指没有参数的构造函数)在C++语言中是一种让你无中生有的方法.构造函数能初始化对象,而缺省构造函数则可以不利用任何在建立对象时的外部数据就能初始化对象.有时这样的方法是不错的.例如一些行为特性与数字相仿的对象被初始化为空值或不确定的值也是合理的,还有比如链表.哈希表.图等等数据结构也可以被初始化为空容器. 但不是所有的对象都属于上述类型,对于很多对象来说,不利用外部数据进行完全的初始化是不合理的.比如一个没有输入姓名的地址簿对象,就没有任何意

C++中的const对象与缺省构造函数问题

先看一个“奇怪”的错误: #include <iostream> #include <stdlib.h> using namespace std; class A{ private: int sad; public: void f() const; void f1(); //A(int); //A(); }; void A::f() const{ cout<<"dfsdfds"; } void A::f1(){ cout<<"f

c++基础语法之构造函数和初始化表

笔者刚系统的重学了c++的语法,看到构造函数和初始化表这块,发现这块语法有点复杂且很杂,怕以后忘记,于是写下此篇,以后回忆之用. c++构造函数 3.构造函数(constructor) Class/struct  类名 { //构造函数 类名(形参表) {函数体} }: 1)构造函数名字和类名相同,没有返回类型 2)构造函数在对象被创建时自动被调用 3)构造函数主要负责对象的初始化,即初始化成员变量 4)构造函数在每个对象的生命周期,一定会被自动调用,但只会被调用一次 Class  A { A(

C#编程基础:静态构造函数

静态构造函数可能一般对于它有点陌生,静态构造函数是C#的一个新特性,在编程过程中用处并不广,它的主要目的是用于初始化一些静态的变量.可以参考C#入门基础01教程. 1.静态构造函数既没有访问修饰符,也没有参数.因为是.NET调用的,所以像public和private等修饰符就没有意义了. 2.是在创建第一个类实例或任何静态成员被引用时,.NET将自动调用静态构造函数来初始化类,也就是说我们无法直接调用静态构造函数,也就无法控制什么时候执行静态构造函数了. 3.一个类只能有一个静态构造函数. 4.

C++学习基础十——子类构造函数与析构函数的执行

1.子类构造函数的执行: 先执行父类的构造函数,再执行成员对象的构造函数,最后执行自身的构造函数. 当继承多个类时,构造函数的 执行顺序与继承时的顺序 相同,而与子类构造函数调用父类构造函数的顺序无关. 2.子类析构函数的执行: 先执行自身析构函数,再执行成员对象的析构函数,最后执行父类的析构函数 . 当继承多个类时,父类析构函数的执行过程与构造函数的执行过程相反 3.代码如下: 1 #include <iostream> 2 #include <string> 3 4 using

C++学习基础六——复制构造函数和赋值操作符

1.什么是复制构造函数 复制构造函数:是构造函数,其只有一个参数,参数类型是所属类的类型,且参数是一个const引用. 作用:将本类的成员变量赋值为引用形参的成员变量. 2.什么是赋值操作符 赋值操作符:返回值是本类的引用类型,参数类型是所属类的类型,且参数是一个const引用. 作用与复制构造函数相同. 其声明如下: 1 Sales_item& operator=(const Sales_item& rig); 3.什么情况下需要我们自己实现复制构造函数和赋值操作符? 一般情况下,C++