6

I'm having a class that looks like:

class A { public: A(float v) { A::v = v; } float v; float set(float v) { A::v = v; return v; } float get(float v) { return A::v; } }; 

Then I instantiate 2 objects of class A:

A* a = new A(1.0); A* b = new A(*a); 

Why are there no errors when my Class A doesn't have a constructor which takes a class A?

8
  • 4
    Aside: get takes an argument: float get(float v) -- but that's not a common expectation/idiom. You may want to change that. Commented May 10, 2019 at 15:08
  • 2
    Are you sure your book doesn't cover this? Commented May 10, 2019 at 15:11
  • 1
    Surprised the syntax highlighter has pulled up set. Ish Commented May 10, 2019 at 15:11
  • @LightnessRacesinOrbit: What's the world coming to? Commented May 10, 2019 at 15:12
  • @Bathsheba An end. Slowly :) Commented May 10, 2019 at 15:13

3 Answers 3

11

The compiler generates a copy constructor for you:

If no user-defined copy constructors are provided for a class type (struct, class, or union), the compiler will always declare a copy constructor as a non-explicit inline public member of its class.

You can make the copy constructor and assignment deleted and make the compiler not declare move assignment and constructor by declaring one of move constructor or assignment as deleted:

A(A&&) = delete; // Makes the class non-copyable and non-moveable. 
Sign up to request clarification or add additional context in comments.

4 Comments

Upvoted as it seems that I have plagiarised your snippet! (Feel free to include any bits from my answer too - this looks to me to be the best answer of the current crop).
Is there really no dupe that covers this? That's a lot of answers for a question I could swear I've seen yesterday...
@Bathsheba Yours is a rather rare beast A(A const&&).
@MaximEgorushkin: Last edit and a wiki as promised. It's hardly "my" answer any more!
8

It does have the copy constructor: the compiler has generated one for you.

If you want to disable that explicitly, then write

A(const A&) = delete; 

in the class declaration; and using

A(A&&) = delete; 

deletes all the rule of five functions, except the destructor.

4 Comments

The compiler still generates the assignment operator though.
@MaximEgorushkin: Yup indeed, added the idiomatic way of dealing with that.
nitpick: destructor still generated
One more fix and I'll wiki this!
5

An implicit copy constructor is generated by the Compiler, if you do not specify an own.

One further note:

Try

A a = 3.0f; 

Conclusion: always mark constructors that take a single basic data type as explicit ... unless you like the implicit conversion

4 Comments

"always mark constructors that take a single basic data type as explicit" ... unless you like the implicit conversion.
That advice is out of date; you need to mark multi-argument constructors explicit too to obviate initialisation using {}.
@Bathsheba I'd argue you're still less likely to want to explicit those, but it's possible
@BrianCain of course you are right. but in my expierence it is wanted rather seldom, maybe if you imeplement some number class that should behave transparently.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.