C++-一个c++构造函数的疑问

WP主题讨论 WP主题讨论 主题:1013 回复:2239

C++-一个c++构造函数的疑问

甜柠檬 发布于 2017-09-04 字数 927 浏览 1001 回复 9
//#include <iostream>
//using namespace std;
#include <Windows.h>

class student
{
public:
student(){OutputDebugStringA("student()n");}
/*explicit */student(const char* s){OutputDebugStringA("student(const char* s)n");}
student(const student& stu){OutputDebugStringA("student(const student& stu)n");}
student& operator = (const student& stu){OutputDebugStringA("student& operator = (const student& stu)n"); return *this;}
};
int main()
{
student s1;
OutputDebugStringA("n");
student s2("11");
OutputDebugStringA("n");
student s3 = "11";
OutputDebugStringA("n");
student s4 = s3;
OutputDebugStringA("n");
student s5;
s5 = "11";
OutputDebugStringA("n");
student s6;
s6 = s5;
return 0;
}

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

支持 Markdown 语法,需要帮助?

评论(9

晚风撩人 2017-10-19 9 楼

你的程序有点问题。
这部分代码:

student& operator = (const char* s){
    OutputDebugStringA("student& operator = (const char* s)n");
    return *this;
}

如果按照你的意思,调用这个操作符的话,因为这个函数体内并没有初始化类对象的操作,因此类对象并没有被正确的构造出来。所以是错误的。要想正确的调用这个操作符,还是的调用构造函数或者是拷贝赋值操作符。
所以平时基本不怎么见到这样的操作符定义。
平时用的多的就是构造函数、拷贝构造函数、拷贝赋值函数。
拷贝构造函数实例:

#include <iostream>  
using namespace std;  

class Test
{
public:
Test(int temp)
{
p1=temp;
}
private: int p1;
};

int main()
{
Test a(99);
Test b=a; //调用拷贝构造函数,而非赋值 }

而赋值是针对已经初始化了的对象进行的操作。
比如:

Test a(99);  
Test c;
c = a;////调用拷贝赋值函数
夜无邪 2017-10-16 8 楼

C++中, 一个参数的构造函数(或者除了第一个参数外其余参数都有默认值的多参构造函数), 承担了两个角色。 1 是个构造器 2 是个默认且隐含的类型转换操作符。
explicit就是用来防止由构造函数定义的隐式转换的,换句话说即禁止其饰演上面所阐述的角色2。

瑾兮 2017-09-30 7 楼

explicit就是用来防止由构造函数定义的隐式转换的。
建议参考http://www.cnblogs.com/winnersun/archive/2011/07/16/2108440.html

瑾兮 2017-09-26 6 楼

江南烟雨说的很对 想顶但是不够15积分 汗
1.student& operator = (const char s){
2.OutputDebugStringA("student& operator = (const char
s)n");
3.return *this;
4.}

确实 重载=操作符 和系统自动生成的copy构造函数一起使用

而返回的this指针的解析根本就不存在 因为根本没有成功构造出一个student

student& operator = (const student& stu)
{
OutputDebugStringA("student& operator = (const student& stu)n");
return ((student*)this = (new student));//去除this的cost属性
}

泛泛之交 2017-09-23 5 楼

/explicit /student(const char s){OutputDebugStringA("student(const char s)n");}
student s3 = "11";
上述构造函数针对其下面的代码,如果没有ecplict修饰符,则会先创建一个student对象,将“11”隐式转换成char ,相当于student sTemp("11");然后再把sTemp复制给s3。
如果有了explict修饰符,则不会将“11”给隐式的转换成char
,那么就没有相对应的构造函数来使用,因此报错。
student s3 = "11";这段代码,由于你已经对“=”重载,而重载是需要一个student &,所以编译器为了把执行这段代码,就得先把“11”隐式转换成char ,调用student(const s)生成一个student &。但是explicit禁止隐式转换,因此失败了。

甜柠檬 2017-09-20 4 楼

explicit 这个说明了构造函数是显示调用的。何为显示调用 即:
student s1; 这才是显示调用。
student s2(s1); 这才是显示调用。
student s3 = "11"; 这个是隐式调用,你认为这里会调用拷贝够着函数explicit student(const char s) 是错误的。它想找一个能够隐式调用的构造函数,但却找不到。 而且这种初始化时不会调用
operator= 赋值操作的。
student s3 = "11"; //这里是初始化。
是不会调用student& operator = (const char
s)的,你写了也没用。因为这个是赋值,何为赋值,赋值的意思就是给原有已经创建的对象新的值。所以它只能报错。

瑾兮 2017-09-17 3 楼

student s3 = "11"这句从语义上来说应该等于student s3 = student("11")。
这里应该有一个const char*单形参构造函数的调用和一个复制构造函数的调用,结果中没有显示复制构造函数调用是由于编译器的优化(临时对象拷贝到同类型的对象,编译器可以选择省略复制构造的过程,直接构造到最终对象中)。
添加explicit后语义不满足(因为不能隐式的转换为student对象),所以报错。

归属感 2017-09-17 2 楼

单参构造函数造成的隐式转换问题。

偏爱自由 2017-09-04 1 楼

建议看一下《Inside the C++ object mode》