Why does copy constructor hide the default constructor in C++? - c++

#include <iostream>
#include <conio.h>
using namespace std;
class Base
{
int a;
public:
Base(const Base & b)
{
cout<<"inside constructor"<<endl;
}
};
int main()
{
Base b1;
getch();
return 0;
}
This gives an error. no matching function for call to `Base::Base()'
Why?

The default constructor is only generated if you don't declare any constructors. It's assumed that if you're defining a constructor of your own, then you can also decide whether you want a no-args constructor, and if so define that too.
In C++0x, there will be an explicit syntax for saying you want the default constructor:
struct Foo {
Foo() = default;
... other constructors ...
};

It does not hide the default constructor, but declaring any constructor in your class inhibits the compiler from generating a default constructor, where any includes the copy constructor.
The rationale for inhibiting the generation of the default constructor if any other constructor is present is based on the assumption that if you need special initialization in one case, the implicitly generated default constructor is most probably inappropriate.

Related

why does my class only work with two constructors c++

This does not work
When I don't have a blank constructor in my class the code will not run causing an error saying no default constructor exists for class.
#include <iostream>
class myClass
{
public:
myClass(int val)
:x(val)
{}
private:
int x;
};
int main()
{
myClass random;
return 0;
}
This works
#include <iostream>
class myClass
{
public:
myClass(int val)
:x(val)
{}
myClass()
{}
private:
int x;
};
int main()
{
myClass random;
return 0;
}
This is because when you try to instantiate the object myClass random, you are trying to invoke the default constructor which you do not have.
If you changed it to myClass random(3)( basically trying to invoke the constructor that you have), you would see that the compiler would have no problems.
If you want myClass random to compile fine, then you must have a default constructor in your class.
Once you declare a constructor in a class (any constructor), the compiler won't automatically generate a default constructor for you (this is what you're calling the blank constructor).
If you don't want to implement the default constructor (generally a good idea if you just want the default behavior), you can tell the compiler to generate it for you as of C++11.
class myClass {
public:
myClass(int val)
:x(val)
{}
myClass() = default; // the compiler handles the implementation
private:
int x;
};
In the first case you have defined a parameterized constructor. When a constructor is defined the compiler now does not automatically define a default constructor like before.
If no constructor is defined the compiler automatically defines a default constructor but if another constructor is defined the compiler will not do so.
i.e. in first case a default constructor does not exist. In the second case you have defined one and hence has no errors.
See default constructor.
If no user-declared constructors of any kind are provided for a class type, the compiler will always declare a default constructor as an inline public member of its class.
However, there's a constuctor declared in your class, thus the compiler won't declare a default constructor. You have to explicitly declare one yourself.

Constructor of the base is not made available by the using declaration [duplicate]

I've been searching for this and I'm amazed I haven't found anything. Why can't I inherit a base class constructor using using declaration and add an overload in the derived class? I'm using Visual C++ 2013, the base class constructor is ignored when default-constructing b:
error C2512: 'B' : no appropriate default constructor available
I've dealt with this by re-defining the constructors, but I don't like that. This is just a minimal example, it wouldn't bother me if I had only one base class constructor.
struct A
{
A() : a(10) {}
int a;
};
struct B : A
{
using A::A;
explicit B(int a) { this->a = a; }
};
int main()
{
B b;
}
The problem is that default-constructors are not inherited. From [class.inhctor]/p3:
For each non-template constructor in the candidate set of inherited constructors [..], a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the complete class where the using-declaration appears or the constructor would be a default, copy, or move constructor for that class.
You also have a user-declared constructor that suppresses the creation of an implicit default-constructor. Just add a defaulted one to make it work:
B() = default;

Constructor with default arguments can not be called when inherited [duplicate]

I've been searching for this and I'm amazed I haven't found anything. Why can't I inherit a base class constructor using using declaration and add an overload in the derived class? I'm using Visual C++ 2013, the base class constructor is ignored when default-constructing b:
error C2512: 'B' : no appropriate default constructor available
I've dealt with this by re-defining the constructors, but I don't like that. This is just a minimal example, it wouldn't bother me if I had only one base class constructor.
struct A
{
A() : a(10) {}
int a;
};
struct B : A
{
using A::A;
explicit B(int a) { this->a = a; }
};
int main()
{
B b;
}
The problem is that default-constructors are not inherited. From [class.inhctor]/p3:
For each non-template constructor in the candidate set of inherited constructors [..], a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the complete class where the using-declaration appears or the constructor would be a default, copy, or move constructor for that class.
You also have a user-declared constructor that suppresses the creation of an implicit default-constructor. Just add a defaulted one to make it work:
B() = default;

Inherit and overload default constructor

I've been searching for this and I'm amazed I haven't found anything. Why can't I inherit a base class constructor using using declaration and add an overload in the derived class? I'm using Visual C++ 2013, the base class constructor is ignored when default-constructing b:
error C2512: 'B' : no appropriate default constructor available
I've dealt with this by re-defining the constructors, but I don't like that. This is just a minimal example, it wouldn't bother me if I had only one base class constructor.
struct A
{
A() : a(10) {}
int a;
};
struct B : A
{
using A::A;
explicit B(int a) { this->a = a; }
};
int main()
{
B b;
}
The problem is that default-constructors are not inherited. From [class.inhctor]/p3:
For each non-template constructor in the candidate set of inherited constructors [..], a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the complete class where the using-declaration appears or the constructor would be a default, copy, or move constructor for that class.
You also have a user-declared constructor that suppresses the creation of an implicit default-constructor. Just add a defaulted one to make it work:
B() = default;

SomeClass* initialEl = new SomeClass[5];

Should SomeClass* initialEl = new SomeClass[5]; necessarily compile, assuming SomeClass does not have a non-publicly declared default constructor? Consider:
/*
* SomeClass.h
*
*/
#ifndef SOMECLASS_H_
#define SOMECLASS_H_
class SomeClass
{
public:
SomeClass(int){}
~SomeClass(){}
};
#endif /* SOMECLASS_H_ */
/*
* main.cpp
*
*/
#include "SomeClass.h"
int main()
{
SomeClass* initialEl = new SomeClass[5];
delete[] initialEl;
return 0;
}
Assuming SomeClass has a publicly accessible default constructor, yes.
Note that there is a difference between
having a publicly accessible default constructor (what i said) and
not having a non-publicly declared default constructor (what you said)
For the following class 2. is true but 1. is not:
class A {
SomeClass(const SomeClass&) {}
};
This is due to §12.1/5 (C++03):
If there is no user-declared constructor for class X, a default constructor is implicitly declared.
An implicitly-declared default constructor is an inline public member of its class.
With your update, SomeClass doesn't have a default constructor. You didn't declare one and because you have declared another constructor the compiler won't declare it implicitly either.
If you need one you have to implement it yourself:
class A {
public:
SomeClass(int) {}
SomeClass() {}
};
Or let another constructor qualify as a default constructor:
class A {
public:
SomeClass(int=0) {}
};
No, it won't compile without a default constructor. There is no compiler-generated default constructor in this case, because you have defined another constructor. "The compiler will try to generate one if needed and if the user hasn't declared other constructors." -- The C++ Programming Language, Stroustrup
If you really want to use new SomeClass[5], you'll have to provide a default constructor as well.