Constructor ill-formness and implicit deletion - c++

I'm trying to define some classes but I get some errors I'm not being able to decode.
I do not understand why it states I'm using Test's constructor when I am not.
test.cpp: In constructor 'Test2::Test2(int)':
test.cpp:12:34: error: use of deleted function 'Test::Test()'
explicit Test2(const int line) {}
^
test.cpp:3:7: note: 'Test::Test()' is implicitly deleted because the default definition would be ill-formed:
class Test : public std::runtime_error {
^
test.cpp:3:7: error: no matching function for call to 'std::runtime_error::runtime_error()'
test.cpp:3:7: note: candidates are:
In file included from test.cpp:1:0:
C:/Development/MinGW/x86_64-w64-mingw32/include/c++/stdexcept:119:5: note: std::runtime_error::runtime_error(const string&)
runtime_error(const string& __arg);
^
C:/Development/MinGW/x86_64-w64-mingw32/include/c++/stdexcept:119:5: note: candidate expects 1 argument, 0 provided
C:/Development/MinGW/x86_64-w64-mingw32/include/c++/stdexcept:112:9: note: std::runtime_error::runtime_error(const std::runtime_error&)
class runtime_error : public exception
^
C:/Development/MinGW/x86_64-w64-mingw32/include/c++/stdexcept:112:9: note: candidate expects 1 argument, 0 provided
Minimal working example (gcc 4.9.1, g++ -std=c++11):
#include <stdexcept>
class Test : public std::runtime_error {
public:
virtual ~Test() noexcept {}
virtual const char * what() const noexcept = 0;
};
class Test2 : public Test {
public:
explicit Test2(const int line) {}
virtual const char * what() const noexcept { return ""; }
};

Your constructor in the class Test2 does not pass any arguments to the base class. So the default constructor of the base class - which is Test - is used. And the same story with Test then - its default constructor tries to call the default constructor of its base class - std::runtime_error - which does not exist. Hence the error. You need to pass message string argument to std::runtime_error, e.g.:
Test() : std::runtime_error("some message") {}

Related

C++ - Overriding Virtual Templated Member Functions

In this example:
class MyClass
{
public:
MyClass(int i);
};
template<typename T>
class Base
{
public:
virtual std::unique_ptr<T> createObj()
{
return std::make_unique<T>();
}
};
class Derived : public Base<MyClass>
{
public:
std::unique_ptr<MyClass> createObj() override
{
return std::make_unique<MyClass>(4);
}
};
int main()
{
Derived instance;
auto createdObj = instance.createObj();
}
I cannot call the derived createObj() function. It seems the code is trying to still call the base version with the MyClass instance which leads to compilation failures since the required construction arguments are not passed. Why does this not work as a normal overriden function and call the derived version that does supply the correct arguments?
You misinterpreted the error. The error message is:
In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-10.3.0/lib/gcc/x86_64-linux-gnu/10.3.0/../../../../include/c++/10.3.0/memory:83:
/opt/compiler-explorer/gcc-10.3.0/lib/gcc/x86_64-linux-gnu/10.3.0/../../../../include/c++/10.3.0/bits/unique_ptr.h:962:34: error: no matching constructor for initialization of 'MyClass'
{ return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
^
<source>:15:21: note: in instantiation of function template specialization 'std::make_unique<MyClass>' requested here
return std::make_unique<T>();
^
<source>:19:7: note: in instantiation of member function 'Base<MyClass>::createObj' requested here
class Derived : public Base<MyClass>
^
<source>:6:5: note: candidate constructor not viable: requires single argument 'i', but no arguments were provided
MyClass(int i);
^
<source>:3:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
class MyClass
^
<source>:3:7: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided
1 error generated.
Base<MyClass> tries to default construct a MyClass but MyClass has no default constuctor. Even if you are not trying to call Base<MyClass>::createObj the method must be valid because it is instantiated as part of Base<MyClass>.
In other words, merely instantiating Base<MyClass> will fail. Not calling the method does not make it less of an error.
I am not entirely sure whats the aim, but if you make the method pure virtual in Base your code compiles without issues:
#include <memory>
class MyClass
{
public:
MyClass(int i) {}
};
template<typename T>
class Base
{
public:
virtual std::unique_ptr<T> createObj() = 0;
};
class Derived : public Base<MyClass>
{
public:
std::unique_ptr<MyClass> createObj() override
{
return std::make_unique<MyClass>(4);
}
};
int main()
{
Derived instance;
auto createdObj = instance.createObj();
}
Alternatively you could provide a default contructor for MyClass.

How are constructors with default parameters called in inheritance hierarchy? [duplicate]

This question already has an answer here:
Why is Default constructor called in virtual inheritance?
(1 answer)
Closed 2 years ago.
I have this simple code:
class C0
{
public:
C0(std::string i) : i_(i) {}
private:
std::string i_;
};
class C1 : public virtual C0
{
public:
constexpr static auto const e{"e"};
C1(std::string i = e) : C0(i) {}
};
class C2 : public virtual C1
{
public:
C2(std::string k) : k_(k) {}
private:
std::string k_;
};
Compiled as: [clang++|g++] -std=c++17 example.cpp
I get the following error:
With g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0:
example.cpp: In constructor ‘C2::C2(std::__cxx11::string)’:
example.cpp:23:41: error: no matching function for call to ‘C0::C0()’
C2(std::string k) : k_(k) {}
^
example.cpp:6:17: note: candidate: C0::C0(std::__cxx11::string)
C0(std::string i) : i_(i) {}
^~
example.cpp:6:17: note: candidate expects 1 argument, 0 provided
example.cpp:3:7: note: candidate: C0::C0(const C0&)
class C0
^~
example.cpp:3:7: note: candidate expects 1 argument, 0 provided
example.cpp:3:7: note: candidate: C0::C0(C0&&)
example.cpp:3:7: note: candidate expects 1 argument, 0 provided
With clang++ version 6.0.0-1ubuntu2:
example.cpp:23:17: error: constructor for 'C2' must explicitly initialize the base class 'C0' which does not have a default constructor
C2(std::string k) : k_(k) {}
^
example.cpp:3:7: note: 'C0' declared here
class C0
^
Why does the compiler complain about missing default constructor in class C0 when the default constructor of class C1 explicitly calls C0 constructor passing the argument?
When I define a default constructor in C0, the call to C0(i) from C1 does not happen. So the member variable C0::i_ is not initialised. Shouldn't there be a call to C0(i) rather than the default constructor of C0 when C2 is instantiated?
The most derived class is the one that is responsible for constructing the virtual bases. To fix this, add : C0(k) to C2.

Initializing base class const member in most derived class

In the below code, I initialize const member of Base class in the most derived class Grandchild.
class Base {
public:
Base(int x_) : x(x_) {}
private:
const int x;
};
class Child : public virtual Base {
public:
virtual ~Child() = 0;
};
class Grandchild : public virtual Child {
public:
Grandchild() : Base(42) {}
};
Child::~Child() {}
int main() {
Grandchild gc;
}
In case of virtual inheritance, the Base class constructor is called by the most derived class. Hence, I expect the code to compile successfully.
clang 4.0 compiles it successfully, whereas gcc 4.9.2 emits the following error:
In constructor 'Grandchild::Grandchild()':
16:27: error: use of deleted function 'Child::Child()'
9:7: note: 'Child::Child()' is implicitly deleted because the default definition would be ill-formed:
9:7: error: no matching function for call to 'Base::Base()'
9:7: note: candidates are: 3:5: note: Base::Base(int)
3:5: note: candidate expects 1 argument, 0 provided
1:7: note: constexpr Base::Base(const Base&)
1:7: note: candidate expects 1 argument, 0 provided
1:7: note: constexpr Base::Base(Base&&)
1:7: note: candidate expects 1 argument, 0 provided
What does the standard say about this?
It seems there was a change in the C++ standard clarifying the requirements of generated constructors for virtual base classes. See CWG257. As far as I understand this text your situation should be allowed. Prior to the change the situation was unclear.
This change was voted into the Working Paper in October 2009, i.e., it should be applicable to compiling with C++11.

gmock with base class constructor

I'm getting a compiler error, which I don't understand why. Or rather, I believe I'm doing what it telling me to. (Or not doing what I shouldn't do)
// InterfaceClass.h
class InterfaceClass {
public:
explicit InterfaceClass(DependencyClass * const p_dc);
};
// MockClass.h
class MockClass : public InterfaceClass {
public:
explicit MockClass(DependencyClass * const p_dc) : InterfaceClass(p_dc) {}
};
// test_MyTest.cpp
class MyTestFixture : public testing::Test {
protected:
MockDependencyClass mock_dependency;
NiceMock<mocks::MockClass> mock;
public:
MyTestFixture() : mock(&mock_depedency) {}
};
The error I'm getting when compiling my test is this:
In file included from test/test_MyTest.cpp:2:
In file included from vendor/googlemock/include/gmock/gmock.h:62:
vendor/googlemock/include/gmock/gmock-generated-nice-strict.h:92:12: error: constructor for 'testing::NiceMock<MockClass>' must explicitly initialize the base class 'InterfaceClass' which does not have a default constructor
explicit NiceMock(const A1& a1) : MockClass(a1) {
^
test/test_MyTest.cpp:43:30: note: in instantiation of function template specialization 'testing::NiceMock<MockClass>::NiceMock<DependencyClass *>' requested here
MyTestFixture(void) : mock(&mock_dependency) {
^
src/InterfaceClass:21:7: note: 'InterfaceClass' declared here
class InterfaceClass {
^
So, if I'm understanding this correctly, its telling me that my mock cannot initialise the interface class, because there is no default constructor and I haven't specified a non-default constructor to use. But I have? And if I understand gmock's source correctly, it supports constructors with up to 10 parameters.
And in my test fixture; if I make the mock a regular mock (i.e. not a NiceMock), it compiles.
What am I doing wrong here?

no matching function for call to ..constructor

I am trying to compile a code that involves inheritance.
#include "MapEntityClass.h"
class RectangularEntityClass:public MapEntityClass
{
public:
void drawOnMap(MapClass *mapObj) const;
protected:
};
The parent class is MapEntityClass, which does not have a default constructor, but has a value constructor. When I compile, I get the following error:
RectangularEntityClass.h: In constructor ‘RectangularEntityClass::RectangularEntityClass()’:
RectangularEntityClass.h:12:7: error: no matching function for call to ‘MapEntityClass::MapEntityClass()’
class RectangularEntityClass:public MapEntityClass
^
RectangularEntityClass.h:12:7: note: candidates are:
In file included from main.cpp:1:0:
MapEntityClass.h:32:5: note: MapEntityClass::MapEntityClass(const PixelLocationClass&, const ColorClass&)
MapEntityClass(
^
MapEntityClass.h:32:5: note: candidate expects 2 arguments, 0 provided
Any idea what is wrong?
In inheritance, the subclass need not have a constructor only if parent class doesn't have a constructor or only default constructor.
In any case, if parent class happens to have a parameterized constructor, the subclass should have a parameterized constructor which should invoke the parent class constructor.
Example:
class A {
int aVal;
public:
A(int);
};
A::A(int aVal)
{
this->aVal = aVal;
}
class B : public A {
int bVal;
public:
B(int, int)
};
B::B(int aVal, int bVal) : A(aVal)
{
this->bVal = bVal;
}