3

Suppose i have a class "myclass" -:

class myclass
{
public:
    int n;
    myclass(int n=0)
    {
        this->n=n;
    }
    myclass(myclass &a)
    {
        this->n=a.n;
    }
    ~myclass()
    {
        cout<<n<<"\n";
    }
};  

Now i want to create an array of objects of "myclass" as follows -:

int main()
{
    myclass arr[]= {5};  // Only 1 element for simplicity...
}

But when i do this , i get the following error -:

In function ‘int main()’:
|47|error: no matching function for call to ‘myclass::myclass(myclass)’
|47|note: candidates are:
|36|note: myclass::myclass(myclass&)
|36|note: no known conversion for argument 1 from ‘myclass’ to ‘myclass&’
|32|note: myclass::myclass(int)
|32|note: no known conversion for argument 1 from ‘myclass’ to ‘int’

But when i remove the copy constructor myclass(myclass &a) from the class , i don't get any errors and everything works fine...

So now my questions are -:

1). Why is this happening?? Isn't myclass(int n=0) a better match than the copy constructor here??

2). How to successfully compile it , considering I want both , the copy constructor as well as the integer constructor in my class??

NOTE: I am using GCC version 4.7.3 on Ubuntu 13.04 ( If it is of any relevance. )

2
  • 1
    Shouldn't a copy constructor take a const myclass& a? Commented Jul 11, 2013 at 15:50
  • @nvoigt Both are legal, and there are rare cases (like std::auto_ptr) where the copy constructor does take a non-const reference. But generally: you want to be able to copy temporaries (which requires a const ref), and you don't modify the object being copied (so you can use a const ref). Commented Jul 11, 2013 at 16:00

2 Answers 2

2

The initialization semantics in this case are copy initialization. Copy initialization formally converts the arguement, then copies it. The converted arguement is not an lvalue, so it cannot bind to the non-const reference in your copy constructor. If you don't define the copy constructor, the compiler defines one for you, which takes a const reference. You're copy constructor should take a const reference as well, since it doesn't modify its argument.

Note that the compiler is allowed to optimize out the copy construction. But only if the program would be legal if it didn't.

Sign up to request clarification or add additional context in comments.

1 Comment

I would have voted it up but I don't have enough reputation.I'll vote it as soon as i get some. Thanks for the help anyways..!!
2

How to successfully compile it , considering I want both , the copy constructor as well as the integer constructor in my class?

Adding const to the reference argument of the copy constructor fixes this problem:

myclass(const myclass &a) : n(a.n) {}

Demo on ideone.

4 Comments

Oh yeah! Forgot that "5" is a const value. Thanks a lot!
@AnmolSinghJaggi 5 has type int, not int const; it's an rvalue, so cannot be cv-qualified. And the 5 serves as argument to myclass( int ). It's the copy of the temporary object created by myclass( int ) which fails if the copy constructor takes a non-const reference.
@JamesKanze You are right! But what do you mean by "cv-qualified" exactly??
@AnmolSinghJaggi Being qualified by const or volatile. ("cv-qualified" is the term used in the standard for this.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.