C++中constructor的问题
巴扎黑
巴扎黑 2017-04-17 13:52:45
0
4
596
  1. 最近开始学习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

希望有大神帮忙解决...

巴扎黑
巴扎黑

reply all(4)
巴扎黑

Test y = "haha";

  1. In this statement, the compiler first uses Test(char ptr) to implicitly convert the string into the Test temporary object. The object of this temporary conversion is an rvalue and cannot be potentially modified. Passing a const char type to char* generated the first warning.
    2. Then try to find a copy constructor and assign this temporary object object to y. The compiler only found Test(Test& test). There is no const modification here. The compiler refused to pass it and reported the second error. The third tip adds that the chosen copy constructor is Test(Test& test).

The most troublesome thing about C++ is the complexity. Each compiler has inconsistent interpretation or leniency of the specifications. Therefore, when using C++, you must not only ensure that there are no errors, but also preferably eliminate all warnings.

左手右手慢动作

Using a const char* to initialize char* is not recommended in C++11 and later, and the compiler will report a warning. Just put the first constructor + const

刘奇

The key is the line of code Test y = “haha”

巴扎黑

A friend reminded me that it might be the compiler. I tried it with vs2015, and it instantly exploded and passed directly (I used the mac terminal before)... What do friends think? I just read the c++ documentation, which is When it comes to copy constructors, they can be const or not.

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.
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template