CPP-Constructors

本文详细介绍了C++中构造函数的概念及其使用方法。包括构造函数的声明与定义、默认构造函数的作用、如何通过构造函数初始化类成员变量以及初始化列表的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当declare一个普通变量时候,可以初始化,类却不允许这么做。例如:

class C{
int i=0; //ERROR, initialization forbidden
const int k=0;//ERROR, initialization forbidden

当declare一个类的对象时候,此对象中所有数据成员是没有初始化的状态,直到用其他方式来初始化此对象。最简单的方式是用constructor来初始化一个类。constructor是一种特殊的初始化函数,此函数在每次一个类的变量被declare时候,或一个类的对象生成的时候自动调用。

constructors的声明(declarations)


class Clock {
public:
    Clock ();
    Clock (int hour,int min,int sec);
    void set(int hour, int min, int sec);
    int read_hour() { return h; }
    int read_min() { return m; }
    int read_sec() { return s; }
    void write(bool write_sec = true);
    void tick();
private:
    int h, m, s;
};

有两个新添加行:

    Clock ();
    Clock (int hour,int min,int sec);

(constructor),构造函数和类同名。此处我们声明了两个构造函数,他们两个有同样的名字Clock. c++中有函数重载机制(同名函数,不同参数)。这也适用成员函数和构造函数。两个构造函数有不同的参数,因此他们被重载。

没有参数而被调用的构造函数叫默认构造函数(default constructor). 如果一个类的构造函数没有被定义,默认构造函数则被自动定义(此处有例外:程序将出现问题,如果类的数据成员是常数,引用或没有默认构造函数的类的类型。另外,一个类不允许有没有默认构造函数的基类)。

自动定义的默认构造函数被调用时,什么都不做。注意构造函数无返回值。

构造函数的定义
构造函数和成员函数定义类似,可以直接在类中定义,或分开单独定义。如果我们想在类中直接定义,则:

Clock () {h=m=s=0;}

构造函数将三个数据成员h,m,s设置为零。如果我们倾向于不将构造函数的定义放在类的定义之中,则给出一个单独的构造函数定义:

Clock::Clock()
{h=m=s=0;}

第二个构造函数可以类似定义:

Clock::Clock(int hour,int min,int sec)
{h=hour;m=min;s=sec;}

此处,成员变量从参数得到初始值。

另外一种赋值方式是在构造函数中采用初始化列表initialization list. 此表显示每一个数据成员的初始化值是多少:

Clock::Clock(int hour,int min,int sec)
: h(hour), m(min), s(sec){}

h,m, s 被初始化为hour,min, sec. 注意一个函数定义必须要有函数体,因此在初始化列表后面必须有一对括号。

以上两种风格也可以混合使用:

Clock::Clock(int hour,int min,int sec) 
: h(hour),m(min){s=sec;}

构造函数中,采用何种初始化方法无所谓。但有时候必须用initialization list。例如,如果我们要初始化的数据成员是常数,或者引用。因为不允许给这种类型的数据赋值,所以必须用initialization list. 此外,initialization lists能生成更高效的代码,所以应该尽可能采用initialization list的方法

<think>好的,我现在遇到了一个C++编译错误:“[Error] only constructors take member initializers”。我需要仔细分析这个问题,找出原因并给出解决方法。 首先,这个错误提示说“只有构造函数可以使用成员初始化器”。可能是在类的成员变量初始化时出现了错误。在C++中,类的数据成员不能在声明时直接初始化,除非使用C++11或更高版本的编译器,并且启用了相关特性。或者在构造函数之外的地方使用了成员初始化列表。 回想一下,成员初始化列表只能出现在构造函数的定义中,用来初始化类的成员变量。如果用户可能在类定义体内直接为成员变量赋值,或者在非构造函数的地方使用了初始化列表,就会导致这个错误。 比如,用户可能写了这样的代码: class MyClass { int a = 10; // C++11允许类内成员初始化 int b; public: void func() : b(20) { // 错误,非构造函数使用了成员初始化列表 } }; 如果用户的编译器不支持C++11,那么在类内直接初始化成员变量a会报错。但根据错误信息,更可能的是在成员函数func中使用了成员初始化列表,而func不是构造函数,所以导致错误。 或者,可能在定义构造函数时,错误地将初始化列表放在了函数体外,或者拼写错误,比如把构造函数的名字写错了,导致编译器认为这是一个普通函数,从而报错。 例如: class MyClass { int a; public: MyClass(int x) : a(x) {} // 正确 void init() : a(5) {} // 错误,init不是构造函数 }; 或者,构造函数的实现中可能错误地使用了成员初始化: MyClass::MyClass(int x) { : a(x) { // 错误,初始化列表应跟在构造函数头后面,而不是在函数体内 } } 这种情况下,初始化列表的语法位置错误,导致编译器报错。 总结可能的原因: 1. 在非构造函数(如普通成员函数)中使用成员初始化列表。 2. 构造函数定义中初始化列表的语法错误,比如放在函数体内。 3. 类内成员初始化时使用了旧版编译器不支持C++11的特性,但错误信息可能不同。 根据错误信息中的“only constructors take member initializers”,最可能的是在非构造函数中使用了成员初始化列表,比如在某个成员函数后误加了初始化列表。 解决方法是检查报错的行号(第15和33行),查看是否有在非构造函数中使用初始化列表的情况。确保成员初始化列表仅出现在构造函数的定义中,并且语法正确。 示例修正: 错误代码: class Test { int x; public: Test() : x(0) {} // 正确 void setX(int val) : x(val) {} // 错误,setX不是构造函数 }; 修正后的代码: class Test { int x; public: Test() : x(0) {} void setX(int val) { x = val; } // 改为在函数体内赋值 }; 另外,检查构造函数的实现是否正确,比如: // 错误示例 Test::Test(int a) { : x(a) // 错误,初始化列表应紧接在构造函数声明之后 } // 正确写法 Test::Test(int a) : x(a) { // 构造函数体 } 总结:该错误通常是由于在非构造函数中使用成员初始化列表,或者构造函数中初始化列表的语法错误导致的。需要检查相关代码行,确保初始化列表仅用于构造函数,并且语法正确。</think><< 错误 "only constructors take member initializers" 表示在非构造函数中错误使用了成员初始化列表。以下是具体原因和解决方法: 1. **错误原因**:在普通成员函数中使用构造函数特有的初始化列表语法 ```cpp // 错误示例 class MyClass { int value; public: void initialize() : value(10) { // 错误:普通函数不能使用初始化列表 // ... } }; ``` 2. **解决方法**: - 对于构造函数:保持正确的初始化列表语法 ```cpp // 正确构造函数写法 class MyClass { int value; public: MyClass() : value(0) {} // 正确:构造函数使用初始化列表 MyClass(int v) : value(v) {} }; ``` - 对于普通成员函数:改用赋值语句初始化 ```cpp // 正确成员函数写法 class MyClass { int value; public: void initialize() { value = 10; // 在函数体内赋值 } }; ``` 3. **特殊注意事项**: - 确保构造函数定义格式正确: ```cpp // 错误的位置 MyClass::MyClass(int x) { // 左大括号提前结束初始化列表 : value(x) // 错误:初始化列表必须在函数体之前 } // 正确的位置 MyClass::MyClass(int x) : value(x) { // 初始化列表紧接参数列表 // 构造函数体 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值