Call to implicitly deleted copy constructor of class error [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I have a class that has a member of type std::thread, however, when I want to use this class as a member of another class I always get the error that the constructor of the other class was implicitly deleted because std::thread constructor is deleted.
My class with the std::thread member looks as follows:
class VideoSender {
public:
VideoSender() : encoderThread([]{}) {};
~VideoSender(){};
private:
std::thread encoderThread;
};
The other class looks like this:
class RemoteCom {
public:
RemoteCom() : videoSender() {};
~RemoteCom(){};
private:
VideoSender videoSender;
};
I was thinking that I already am properly initializing the std::thread class with (here an empty) function. But I still do get this error, so it seems like somewhere there is still a copy constructor called?
I should also add the I can use the VideoSender class directly without errors. This only happens when used as a member of another class.
Edit
I then initialize RemoteCom like this:
RemoteCom com = RemoteCom();
This is really all there is. I reduced it all to this minimal example, the error still exists.

The syntax
RemoteCom com = RemoteCom();
requires a copy constructor to exist and to be accessible. This is true even if optimization would eliminate the call to the copy constructor.
Replace with
RemoteCom com;
which uses the default constructor directly.

Like you have already noticed, std::thread is not copiable, which is why your class' implicit copy constructor is deleted. For this declaration the compiler could utilize the move constructor
RemoteCom com = RemoteCom();
but it cannot, as it is also deleted. C++ standard section 11.4.5.3 §8:
If the definition of a class X does not explicitly declare a move constructor, a non-explicit one will be implicitly declared as defaulted if and only if
X does not have a user-declared copy constructor,
X does not have a user-declared copy assignment operator,
X does not have a user-declared move assignment operator, and
X does not have a user-declared destructor.
As the VideoSender requires a user-declared destructor, because the thread has to joined before it is destructed, I would just declare the move operations explicitly defaulted:
class VideoSender {
public:
VideoSender() = default;
~VideoSender() {
// a moved thread is not joinable
if (encoderThread.joinable()) { encoderThread.join(); }
}
VideoSender(const VideoSender&) = delete;
VideoSender& operator=(const VideoSender&) = delete;
// Move constructor and move assignment operator
// Transfer ownership of the thread to this object
VideoSender(VideoSender&&) noexcept = default;
VideoSender& operator=(VideoSender&&) noexcept = default;
private:
// Brace initializer
std::thread encoderThread{ []{} };
};
For the RemoteCom I would just refer to the rule of zero (C++ Core Guidelines C.20):
class RemoteCom {
// Implicitly declared special member functions are all ok
private:
VideoSender videoSender;
};
With the declarations above the following code would compile on C++14 and C++11:
#include <utility>
// Move construction (may be elided)
RemoteCom com = FunctionReturningARemoteCom();
// Move assignment operator
com = FunctionReturningARemoteCom();
// Move construction
Remote com2 = std::move(com);
With C++17 things are a little bit different because of something called guaranteed copy elision, but that is outside of this answer.

Related

Do I have to define a default constructor for my class if I want to use "new" to allocate an array of it? [duplicate]

This question already has answers here:
Object array initialization without default constructor
(14 answers)
Closed 2 years ago.
Let's say I have a class A :
class A{
public:
A(int const& someValue, std::string const& anotherOne);
private:
std::string m_string_member;
int m_int_member;
};
And I want to allocate an array of this class using new :
A* myClassArray = new A[69];
I get the error : No default constructor available.
Do I have to write a default constructor for every class I want to use by calling new ?
Short answer: Yes.
Long answer: Lets start with this matrix here https://foonathan.net/images/special-member-functions.png. You provide a constructor which is not the default constructor (yours takes arguments). So the compiler won't automagically generate a default constructor for you. However, in your allocation, you ask the compiler to default construct 69 elements. How should the compiler do this? But, solving this issue is rather easy. Just provide the default constructor, or, even easier, use = default. The latter only works because all your members are default-constructible.
In c++ if no user-declared constructors of any kind are provided for a class type the compiler will always declare a default constructor. If you provide any constructor and want default constructor as well, you should define default constructor explicitly.

Why does this operator overloading work? [duplicate]

This question already has answers here:
I defined a non-copy constructor; will a copy constructor still be implicitly defined?
(3 answers)
Closed 6 years ago.
I am trying to learn C++ OOP concepts through an online tutorial where I encountered a code snippet illustrating operator overloading.
The code is shown below:
class MyClass{
int var;
public:
Myclass(int value=0){
var = value;
}
Myclass operator+(Myclass &obj){
Myclass newobj;
newobj.var = this->var + obj.var;
return newobj;
}
};
Suppose I call the operator in the main function like so:
int main(){
...
obj3 = obj2 + obj1;
...
}
During earlier tutorials on Classes, I read about why copy constructors require all parameters to be passed by reference since they themselves are the definition of how to copy two class objects. So, as far as I understand, copy constructors are a must when one has to copy objects of a class.
In the above code snippet, it appears to me that the compiler will try to "copy" the values of newobj onto the L_value in the main() function (obj3). But how is this possible without a copy constructor defined. Have I misunderstood something here?
Thank you for your help!
http://en.cppreference.com/w/cpp/language/copy_constructor#Implicitly-declared_copy_constructor
If you are using standard C++ 2003 or older copy constructor is always implicitly defined (generated by compiler) for any class T unless:
T has non-static data members that cannot be copied (have deleted, inaccessible, or ambiguous copy constructors);
T has direct or virtual base class that cannot be copied (has deleted, inaccessible, or ambiguous copy constructors);
T has direct or virtual base class with a deleted or inaccessible destructor;
If you are using standard C++ 2011 or newer copy constructor is always implicitly defined (generated by compiler) for any class T unless:
T has non-static data members that cannot be copied (have deleted, inaccessible, or ambiguous copy constructors);
T has direct or virtual base class that cannot be copied (has deleted, inaccessible, or ambiguous copy constructors);
T has direct or virtual base class with a deleted or inaccessible destructor;
T has a user-defined move constructor or move assignment operator;
T is a union and has a variant member with non-trivial copy constructor;
T has a data member of rvalue reference type.
Also keep in mind that
a = b;
is not primarily calling copy-constructor but copy-assignment. That in turn is also implicitly defined (auto-generated) if your class if suitable.
For details see: http://en.cppreference.com/w/cpp/language/copy_assignment#Implicitly-declared_copy_assignment_operator

Explicitly declare defaulted methods in C++ [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
According to C++11 standard you can declare special member functions as defaulted using default keyword.
class Foo
{
public:
Foo() = default;
Foo(const Foo& source) = default;
Foo(Foo&& source) = default;
~Foo() = default;
Foo& operator=(const Foo& right) = default;
Foo& operator=(Foo&& right) = default;
};
I was wondering is it a good practice to declare all those methods explicitly defaulted or deleted if you don't need custom implementation of them. For example, I need to implement copy constructor and copy-assignment operator for my class. Should I mark all other special member function with default or delete keywords in order to not think each time I look at a class which are provided by compiler and which are not?
It depends. There are rules to when and whether the compiler will generate those functions automatically. In cases when the compiler wont do that and you need them, you could force it to generate them by using default or implement it yourself. The cases when the compiler wont generate functions are (this is not the full list, please refer to you're compiler's documentation):
no default constructor is generated when a constructor with arguments is declared
no move constructor and move assignment operator is generated when you declare copy constructor and copy assignment operator (and visa-versa)
So, in those cases you might want to bring them back by using default if you know that they'll be needed somewhere. In most cases, however, you should let the compiler do its thing. You'll get an error if one of those functions is not implemented automatically.
P.S. Visual studio does not yet support default and delete for move constructor and move assignment operator, yet.

Why do you have to define an empty constructor c++ [duplicate]

This question already has answers here:
When do we need to have a default constructor?
(7 answers)
Closed 8 years ago.
I have the following classes:
class ArithmeticExpression
{
public:
ArithmeticExpression(std::string expr);
}
class Command
{
public:
Command(){};
//this is a virtual class
}
class CommandAssign : public Command
{
private:
ArithmeticExpression expr;
public:
CommandAssign();
CommandAssign(ArithmeticExpression);
}
Now when I try to write the constructor for the CommandAssign class as in:
CommandAssign::CommandAssign(ArithmeticExpression expr)
:Command()
{
this -> expr = ArithmeticExpression(expr.getExpr());
}
I get the error:
no matching function for call to ‘ArithmeticExpression::ArithmeticExpression()’
:Command()
Apparently I can fix that by adding an empty constructor in ArithmeticExpression class that does not do anything. What is it so special about this empty constructor that makes it work? I do not explicitly call anywhere. Do you always need to define an empty constructor in C++?
I wanted to emphasize that although from the title it seems that my question is similar to the one some users suggested as being a duplicate of, the answer I was looking for is NOT there. I was simply trying to understand what happens when a constructor is called and how to avoid defining a useless default constructor, which I knew already is not automatically defined by the compiler in the case where I define one with parameters.
A default constructor will only be automatically generated by the compiler if no other constructors are defined.
EDIT:
The default constructor is needed for object initialization.
All members are initialised before the constructor body begins. If one doesn't have an entry in the initialiser list, then it will be default-initialised; but this is only possible (for a class type) if it has a default constructor.
expr is not initialised in the initialiser list, and doesn't have a default constructor (since declaring any constructor prevents one from being implicitly generated), so it can't be initialised - hence the error.
You should initialise it in the list, rather than reassigning it in the constructor body:
CommandAssign::CommandAssign(ArithmeticExpression expr) :
expr(expr.getExpr())
{}
Note that there's no need to explicitly default-construct the Command sub-object. This also requires the constructor of ArithmeticExpression to be public: it's private in your example code.

Memberwise Initialization [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++ initialization lists
What is the difference between member-wise initialization and direct initialization in a class?
What is the difference between the two constructors defined in the class?
class A
{
public:
int x;
int y;
A(int a, int b) : x(a), y(b)
{}
A(int a, int b)
{
x = a;
y = b;
}
};
The theoretical answers have been given by other members.
Pragmatically, member-wise initialization is used in these cases :
You have a reference attribute (MyClass & mMyClass) in your class. You need to do a member-wise initialization, otherwise, it doesn't compile.
You have a constant attribute in you class (const MyClass mMyClass). You also need to do a member-wise initialization, otherwise, it doesn't compile.
You have an attribute with no default constructor in your class (MyClass mMyClass with no constructor MyClass::MyClass()). You also need to do a member-wise initialization, otherwise, it doesn't compile.
You have a monstruously large attribute object (MyClass mMyClass and sizeof(MyClass) = 1000000000). With member-wise initialization, you build it only once. With direct initialization in the constructor, it is built twice.
First one uses initialization and second one does NOT use initialization, it uses assignment. In the second one, the members x and y are default-initialized first (with zero), and then they're assigned with a and b respectively.
Also note that in the second one, members are default initialized only if the types of members are having non-trivial default constructor. Otherwise, there is no initialization (as #James noted in the comment).
Now see this topic to know:
What is a non-trivial constructor in C++?