C++ class copy constructor has no matching function

时间:2016-07-11 19:25:55

标签: c++ pointers constructor const

I am trying to write a class Core, it's member variable is a pointer. The copy constructor is Core(Core& x) instead of Core(const Core& x).

Core has a member function Core Core::new_core (int * ptr), the code has a problem when I try to construct Core new_core= core.new_core(ptr);, please see the code and error information below.

#include<iostream>

class Core
{
    private:
    int* a;

    public:
    Core(int* in) {a=in;}
    Core(Core& x) {a = x.data();}

    inline const int * data() const {return a;}
    inline       int * data()       {return a;}

    Core new_core (int * ptr)
    {
        Core b(ptr);
        return b;
    }
};

using namespace std;

int main()
{
    int ptr[3]= {1,2,3};
    Core core(ptr);
    Core new_core= core.new_core(ptr);
    cout<< new_core.data() <<endl;
    return 0; 
}

Error information:

main.cpp: In function ‘int main()’:

main.cpp:30:37: error: no matching function for call to ‘Core::Core(Core)’

Core new_core= core.new_core(ptr);
                                 ^

main.cpp:30:37: note: candidates are:

main.cpp:12:6: note: Core::Core(Core&)

 Core(Core& x) { a = x.data() ;}
 ^

main.cpp:12:6: note: no known conversion for argument 1 from ‘Core’ to >‘Core&’

main.cpp:10:6: note: Core::Core(int*)

 Core(int* in) {a=in;}
 ^

main.cpp:10:6: note: no known conversion for argument 1 from ‘Core’ to ‘int*’

I can easily fix the problem by replacing

Core(Core& x) { a = x.data() ;}

to

Core(const Core& x) { a = const_cast<int* > ( x.data() ) ;}, 

is there a better way to solve the problem without using const_cast?

I want to keep int* a private, and keep following two lines:

inline const int * data() const {return a;}
inline       int * data()       {return a;}

Thank you.

1 个答案:

答案 0 :(得分:4)

The problem here is that new_core returns a Core which is a temporary. When you use it in

Core new_core= core.new_core(ptr);

The compiler calls the copy constructor but it cannot bind to that temporary since it takes a reference. To fix this we can change the copy constructor to take a const Core& which can bind to the temporary and allow you to make a copy.

In this example to get around the const and the use ofconst_cast we can access the class member directly like:

Core(const Core& x) : a(x.a) {}