Heim > Fragen und Antworten > Hauptteil
最近开始学习c++, 自己写了点小代码, 碰到一个问题现在还解决不了.
Test.h
#ifndef GEEK_TEST_H
#define GEEK_TEST_H
#include <cstring>
class Test{
public:
Test(char* ptr){
printf("aaaa");
if(ptr){
this->ptr = new char[strlen(ptr) + 1];
strcpy(this->ptr, ptr);
} else{
this->ptr = new char[1];
ptr[0] = '\0';
}
}
Test(const Test& test){
printf("bbb");
this->ptr = test.ptr;
}
char* ptr;
};
#endif //GEEK_TEST_H
main.cpp
#include <iostream>
#include "Test.h"
using namespace std;
int main() {
Test y = "haha";
return 0;
}
这样编译运行是正常的, 但是当我去掉Test.h中第二个构造函数参数列表中的const
之后, 就报错了... 也就是把第二个构造函数改成这样 :
Test(Test& test){
printf("bbb");
this->ptr = test.ptr;
}
报错也奇怪 :
/Applications/CLion.app/Contents/bin/cmake/bin/cmake --build /Users/zhangzhimin/Library/Caches/CLion2016.1/cmake/generated/geek-ef0ba4bc/ef0ba4bc/Debug --target geek -- -j 8
Scanning dependencies of target geek
[ 50%] Building CXX object CMakeFiles/geek.dir/main.cpp.o
/Users/zhangzhimin/ClionProjects/geek/main.cpp:7:14: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]
Test y = "haha";
^
/Users/zhangzhimin/ClionProjects/geek/main.cpp:7:10: error: no viable constructor copying variable of type 'Test'
Test y = "haha";
^ ~~~~~~
/Users/zhangzhimin/ClionProjects/geek/Test.h:20:5: note: candidate constructor not viable: expects an l-value for 1st argument
Test( Test& test){
^
1 warning and 1 error generated.
make[3]: *** [CMakeFiles/geek.dir/main.cpp.o] Error 1
make[2]: *** [CMakeFiles/geek.dir/all] Error 2
make[1]: *** [CMakeFiles/geek.dir/rule] Error 2
make: *** [geek] Error 2
希望有大神帮忙解决...
巴扎黑2017-04-17 13:54:45
Test y = "haha";
这条语句,编译器首先用 Test(char ptr) 隐式的 字符串转换为 Test 临时对象。这个临时转换的对象是一个右值,不能有潜在的修改。 把一个const char 型 传给 char* ,产生了第一个告警。
2.接着尝式找一个 拷贝构造函数 将这个临时对象对象赋给 y, 编译器只找到了 Test(Test& test), 这里没有 const 修饰, 编译器拒绝传递,报了第二个错误。第三个提示补充说明 选取的 拷贝构造函数 是 Test(Test& test)。
C++ 最头痛的就是复杂性,各编译器对规范的解释或宽严不一致,因些使用C++不仅要保证没有错误,最好还要消除所有的告警。
ringa_lee2017-04-17 13:54:45
拿一个const char* 来初始化 char* 在C++11及以后也是不推荐的,编译器会报warning。你把第一个构造函数+const就好了
巴扎黑2017-04-17 13:54:45
朋友提醒我可能是编译器的原因, 用vs2015试了下, 瞬间爆炸直接通过(之前用的是mac的终端)... 朋友们怎么看, 同时刚看了下c++的文档, 里面说拷贝构造函数, 可以是const的, 也可以不是.
ISO C++03:
12.8
2 A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&,
volatile X& or const volatile X&, and either there are no other parameters or else all other
parameters have default arguments (8.3.6).106) [Example: X::X(const X&) and X::X(X&, int=1)
are copy constructors.