class constructor with const reference - c++

in this class
class Foo {
public:
Foo(){}
Foo(Foo const &) {}
};
when would Foo(Foo const &) ever be called? I do not understand this kind of constructor

This is called copy constructor. When you want to initialize a class instance by copying an existing instance, you'd probably want to use it.
const - you don't want to change the object you are copying.
reference - you don't want to copy the existing instance into the constructor, just to copy it again in the initialization.

Related

Move a std::future to another std::future

I'm trying to move a std::future member of class to another member of same class.
I need to do that because if I want to call std::vector.push_back(MyClass), I need to delete the copy constructor with a simple reference and create another one with double ref because my class contain a std::future member.
When i move the std::future, G++ says :
call to deleted constructor of 'std::future<int>'
_future(std::move(p_myclass._future));
note: 'future' has been explicitly marked deleted here
future(const future&) = delete
But for me, std::move returns a double ref and not a single. So I don't really know where this error comes from.
I tried the assignement operator = with double ref but doesnt work either.
class MyClass
{
private:
std::future<int> _future;
public:
MyClass(const MyClass&) = delete;
MyClass(const MyClass&&);
MyClass& operator=(MyClass &) = delete;
MyClass& operator=(MyClass &&);
};
MyClass::MyClass(const MyClass &&p_myclass) : _future(std::move(p_myclass._future)) {};
MyClass& MyClass::operator=(MyClass &&p_myclass)
{
this->_future = std::move(p_myclass._future);
return (*this);
};
Of course my std::future is initialised on main constructor, but there is no need to paste it here.
Both doesn't work.
Thanks in advice.
p_myclass is const, and then so is p_myclass._future. That's why it can't be moved from; moving from an object requires modifying it. _future(std::move(p_myclass._future)) attempts to copy it instead, but of course std::future is not copyable.

C++ Assignment operator for class that contains a unique pointer member variable

I understand that if I have a class with a smart unique pointer, it is not possible to assign that class to another instance, as a unique pointer cannot be copied. I understand that I could make the unique pointer a shared pointer and this would solve the problem. But what if I did not want to share ownership of the pointer? Is it possible to create an assignment operator that moves the unique pointer and copies the other variables?
I have read that you can use std::move to pass ownership.
#include <iostream>
#include <memory>
struct GraphStructure { };
class test {
int a;
std::vector<int> vector;
std::unique_ptr<GraphStructure> Graph_;
};
int main () {
test t1;
auto t2 = t1;
}
The default copy constructor of class test is deleted because of a member (graph_) not being copiable (if you still could copy in any meaningful way, e. g. by creating a deep copy of the graph member, you'd have to implement on your own copy constructor). In contrast, the default move constructor still exists (std::unique_ptr is movable). So what you can do is the following:
test t1;
auto t2 = std::move(t1);
Be aware, though, that t1 then won't hold any object any more (you moved the object, so you moved its contents to another one) and the object previously held by t2 is destroyed. If this is a meaningful state is up to you to decide...
Side note: What I wrote about copy and move constructors applies for copy and move assignment as well...
Fixing this the easy way
If GraphStructure is a class or struct without any virtual member functions, this is easy to do. We can write a function to duplicate the data inside a unique_ptr to create a new GraphStructure:
std::unique_ptr<GraphStructure> duplicate(std::unique_ptr<GraphStructure> const& ptr)
{
return std::make_unique<GraphStructure>(*ptr);
}
Once we have duplicate, we can use this class to write a copy constructor for test:
class test {
std::unique_ptr<GraphStructure> ptr;
std::vector<int> values;
public:
// this can be defaulted
test() = default;
// we use duplicate to create a copy constructor
test(const test& source)
: ptr(duplicate(source.ptr)))
, values(source.values)
{}
// we can use the default move constructor
test(test&&) = default;
test& operator=(test const& source) {
ptr = duplicate(source.ptr);
values = source.values;
return *this;
}
// we can use the default move assignment operator
test& operator=(test&&) = default;
};
What if GraphStructure has virtual methods?
In this case, add a virtual clone method to GraphStructure that returns a new std::unique_ptr<GraphStructure>:
class GraphStructure {
public:
// override this method in child classes
virtual std::unique_ptr<GraphStructure> clone() {
return std::make_unique<GraphStructure>(*this);
}
virtual ~GraphStructure() {}
};
Then, use .clone() in place of duplicate

Most concise way to disable copying class in C++11

I have a problem dealing with deprecated since C++11 default generation of copy constructor and copy assignment operator when there is a user-defined destructor.
For most sufficiently simple classes default-generated constructors, operators and destructor are fine. Consider the following reasons to declare destructor:
Making trivial destructor virtual in base class:
// header
class Base1 { public: virtual ~Base1() = default; };
class Base2 { public: virtual ~Base2(); };
// source
Base2::~Base2() = default;
Would all 4 copy and move special methods be generated by compiler in these cases? If yes, then I think it is fine and there is no need to complicate Base1 or Base2.
Printing debug message in destructor:
// header
class D { public: ~D(); };
// source
D::~D() {
#ifdef DEBUG_THIS
std::cout << "D was destructed." << std::endl;
#endif
}
I believe that in this case copy constructor and assignment operator would be generated; but move constructor and assignment operator would not. I want to avoid using deprecated default-generating and disable copying of D. I also want to avoid flooding D with 4 deleted declarations. Is disabling only one copy constructor enough? Is it a good style?
With C++11, a clean way is to follow the pattern used in boost (see here)
You basically create a base class where copy constructor and copy assignment are deleted, and inherit it:
class non_copyable
{
protected:
non_copyable() = default;
~non_copyable() = default;
non_copyable(non_copyable const &) = delete;
void operator=(non_copyable const &x) = delete;
};
class MyClass: public non_copyable
{
...
}
Deleting the copy-constructor and copy-assignment operator is the simplest and clearest way to disable copying:
class X
{
X(X const &) = delete;
void operator=(X const &x) = delete;
};
I don't follow what you are talking about with virtual destructors in the question body . It sounds like you're asking for a way to make your code take up fewer characters of source code, but also be more cryptic to anybody looking at it.
If the list of deleted functions bothers you, you could hide them behind a macro, I guess.
#define NON_COPYABLE_NOR_MOVABLE(T) \
T(T const &) = delete; \
void operator=(T const &t) = delete; \
T(T &&) = delete;
Only copy constructor and copy assignment operator will be generated when destructor is explicitly defaulted. And even then their generation is deprecated. So, in order to have virtual destructor and all default methods, one should write the following:
struct Base
{
Base()=default;
virtual ~Base() = default;
Base(const Base&)=default;
Base& operator=(const Base&)=default;
Base(Base&&)=default;
Base& operator=(Base&&)=default;
};
I would definitely use a macro for more than one such Base class.
In case when destructor is defined by user, 2 special methods are still generated. There are the following ways to disable deprecated generating copy constructor and copy assignment operator:
delete move constructor OR move assignment operator (not quite self-explanatory but very short):
Base(Base&&)=delete; // shorter than deleting assignment operator
delete both copy constructor and copy assignment operator:
Base(const Base&)=delete;
Base& operator=(const Base&)=delete;
Note that you have to explicitly declare default constructor if you need it, e.g. Base()=default;.
Macro or inheriting special class can be used as well for this purpose but I personally prefer deleting move constructor to implementing my own macro or base class. When using Qt or boost, I would prefer Q_DISABLE_COPY(Base) and inheriting boost::noncopyable respectively, because they are already implemented, widely known and recognizable.
http://accu.org/index.php/journals/1896 - detailed explanation and rationale for these issues.
You can do it by this(which is used by Caffe: a fast open framework for deep learning):
// Disable the copy and assignment operator for a class.
#define DISABLE_COPY_AND_ASSIGN(classname) \
private:\
classname(const classname&);\
classname& operator=(const classname&)
Usage example:
class CNoCopyable{
public:
CNoCopyable(int i):m_d(i){}
private:
int m_d;
// add this line(pass class name)
DISABLE_COPY_AND_ASSIGN(CNoCopyable);
};

How do you implement a copy constructor when an element doesn't persist in your class?

for example, your constructor might look like this:
myClass::myClass(Mesh &mesh) : baseClass(mesh)
{
pointer = new Thing(mesh);
}
mesh is not held in myClass, nor is there a getter for mesh in baseClass where it is held. Is this simply a case of having to implement a getter in the base class?
for example you cannot do this:
myClass::myClass(const myClass& original) : baseClass(mesh) //there is no mesh
{
pointer = new Thing(mesh); //mesh is no longer in the parameter list
}
How does the compiler make this copy when it creates a default copy constructor for such classes? Or is this a case where a copy constructor is necessary? mesh is not a private member of brain, and there is not getter for it so how do we make a new Thing?
EDIT - Updated the problem by adding Thing
mesh has to be copied inside the baseClass copy constructor.
class baseClass
{
Mesh myMesh;
public:
baseClass(const baseClass &other) : myMesh(other.myMesh) {} // <--- copy Mesh
};
class myClass : public baseClass
{
public:
myClass(const myClass& other) : baseClass(other) {} // <--- simply pass
};
Every class will have to take care of its own copying.
The default copy constructor for myClass will simply call the copy constructor for the base class (and for every other member).
The cannonic copy constructor would be:
MyClass::MyClass( MyClass const& other )
: BaseClass( other )
{
}
The copy constructor for BaseClass would take a const reference to
BaseClass, and other would convert implicitly. The copy constructor
for BaseClass would then do whatever was necessary.
This is the implicitly generated constructor, so you don't have to
provide it, provided you're happy with the other aspects of generated
constructors: public and inline.

Not copyable object and exception in copy constructor and operator=

I'd like to make object of class not copyable so I put copy constructor and operator= in private section. However one class is friend of this class so it has access to private methods. Is it good idea to put throw exception in copy constructor and operator= to be sure that object will not be copied?
One approach to make it not copyable is just to declare the copy constructor, but don't implement it at all. That will force a linker error at compile time if anyone tries to use it.
class foo
{
private:
foo(const foo&); // not defined
foo& operator=(const foo&); // not defined
};
#Mysticial have answered this question which is usually done in C++03. But in C++11, you can do this, more nicely:
class foo
{
private:
foo(const foo&) = delete;
foo& operator=(const foo&) = delete;
};
The =delete conveys the message that foo doesn't support copy-semantic, as it has been disabled by explicitly marking it with delete. I've explained this in detail here:
Is there a way to disable constructor synthesizing on a class?