最近开始学习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.