I'm trying to use move semantics (just as an experiment).
Here is my code:
class MyClass {
public:
MyClass(size_t c): count(c) {
data = new int[count];
}
MyClass( MyClass&& src) : count(src.count) {
data = src.data;
src.count = 0;
src.data = nullptr;
}
void operator=( MyClass&& src) {
data = src.data;
count = src.count;
src.count = 0;
src.data = nullptr;
}
~MyClass() {
if (data != nullptr)
delete[] data;
}
int* get_data() const {
return data;
}
size_t get_count() const {
return count;
}
private:
MyClass(const MyClass& src) : count(src.count) {
data = new int[src.count];
memcpy(data, src.data, sizeof(int)*src.count);
}
void operator=(const MyClass& src) {
count = src.count;
data = new int[src.count];
memcpy(data, src.data, sizeof(int)*src.count);
}
int* data;
size_t count;
};
int main()
{
MyClass mc(150);
for (size_t i = 0; i < mc.get_count(); ++i)
mc.get_data()[i] = i;
MyClass &&mc2 = std::move(mc);
return 0;
}
But std::move does not move mc to mc2, it just copies (copyies pointer as it is). If I remove copy constructor compiler generates it for MyClass.
How can I force move semantics to be used? How can I make it to be used in such constructions:
MyClass mc2(mc); //Move, not copy
-or-
MyClass mc2 = mc; //Move, not copy
I tried to use a '&&' operator to explicitely mark rvalue, but, of cause, it didn't work.
You're declaring m2 as a reference, not as a value. So it still refers to what it was initialised with, namely m1. You wanted this:
MyClass mc2 = std::move(mc);
Live example
As for the second part - there is no way to force a construct like these:
MyClass mc2(mc); //Move, not copy
//-or-
MyClass mc2 = mc; //Move, not copy
to move. If you want to move from an lvalue (and mc is indeed an lvalue), you have to use std::move (or another cast to rvalue) explicitly.
There is one thing you could do, but it would be a dirty hack, make the code unintuitive and be a great source for bugs. You could add an overload of the copy constructor (and copy assignment operator) taking a non-const reference, which would do the move. Basically something like std::auto_ptr used to do before it was rightfully deprecated. But it would never pass code review with me, for example. If you want to move, just std::move.
A few side notes:
Calling delete or delete[] on a null pointer is guaranteed to be a no-op, so you can safely drop the if from your destructor.
It's generally preferable to use std::copy instead of memcpy in C++ code, you don't have to worry about getting the sizeof right
You can force move semantics, if you delete the copy constructor and the assignment operator
MyClass(const MyClass& src)= delete;
void operator=(const MyClass& src) = delete;
in this case the provided move constructor or move assignment operator will be picked.
Rewrite your class a bit with some comments. Look over it, you might notice a few things you missed. Like:
in MyClass(size_t c) not checking for c != 0.
in void operator=(const MyClass& src) not delete[] data; (if exists) before reallocating.
And some other tiny details.Hope your compiler can handle this.
class MyClass {
private:
// initialize memebers directly
int* data = nullptr;
size_t count = 0;
public:
// default empty contructor
MyClass() = default;
// destructor
~MyClass() {
*this = nullptr; // use operator = (nullptr_t)
}
// allow nullptr construct
MyClass(nullptr_t):MyClass() {}
// allow nullptr assignment (for clearing)
MyClass& operator = (nullptr_t) {
if(data) {
delete[] data;
data = nullptr;
}
count = 0;
return *this;
}
// chain to default constructor, redundant in this case
MyClass(size_t c):MyClass() {
// maybe size_t is 0?
if(count = c) {
data = new int[count];
}
}
// chain to default constructor, redundant in this case
MyClass(MyClass&& src):MyClass() {
*this = std::move(src); // forward to move assignment
}
MyClass& operator=(MyClass&& src) {
// don't swap with self
if(&src != this) {
// it's better to swap and let src destroy when it feels like it.
// I always write move contructor and assignment to swap data.
// it's gonna be destroyed anyway, or not...
std::swap(src.data, data);
std::swap(src.count, count);
}
return *this;
}
MyClass(const MyClass& src):MyClass() {
*this = src; // forward to copy assignment
}
MyClass& operator = (const MyClass& src) {
// don't copy to self
if(&src != this) {
// delete first
if(data) {
delete[] data;
data = nullptr;
}
// now reallocate
if(count = src.count) {
data = new int[count];
memcpy(data, src.data, sizeof(int)* count);
}
}
return *this;
}
// easy way to use the object in a if(object) to test if it has content
explicit operator bool() const {
return data && count;
}
// same as above but made for if(!object) to test if empty
bool operator !() const {
return !data || !count;
}
public:
int* get_data() const {
return data;
}
size_t get_count() const {
return count;
}
// add more custom methods
};
Now to move you do this:
MyClass object1; // default construct
MyClass object1(5); // construct with capacity
MyClass object2(object1); // copy constructor
MyClass object3(std::move(object1)); // move constructor
object2 = object1; // copy assignment
object3 = std::move(object1); // move constructor
std::swap(object2, object3); // swap the two
object2 = nullptr; // to empty it
if(object1); // bool cast
Related
class Dummy
{
public:
int* A{};
int num{};
public:
Dummy(int num)
{
this->num = num;
A = new int[num];
}
~Dummy()
{
delete[] A;
}
};
Dummy* dummy()
{
Dummy* d = new Dummy{ 4 };
d->A[0] = 1;
d->A[1] = 2;
d->A[2] = 3;
d->A[3] = 4;
return d;
}
int main()
{
Dummy* ATT = dummy();
}
When I tired to run this program This is always showing Expection at destructor and program can't continue further. What's wrong in this Code...
Your code uses new() and delete() which nowadays in C++ should mostly never be used. Please make yourself comfortable with the appropriate pointer classes which handle memory management for you, like shared_ptr or unique_ptr.
Historically, I've been using trait classes to hold information and apply that into a "generic" function that runs the same "algorithm." Only differed by the trait class. For example: https://onlinegdb.com/ryUo7WRmN
enum selector { SELECTOR1, SELECTOR2, SELECTOR3, };
// declaration
template < selector T> struct example_trait;
template<> struct example_trait<SELECTOR1> {
static constexpr size_t member_var = 3;
static size_t do_something() { return 0; }
};
template<> struct example_trait<SELECTOR2> {
static constexpr size_t member_var = 5;
static size_t do_something() { return 0; }
};
// pretend this is doing something useful but common
template < selector T, typename TT = example_trait<T> >
void function() {
std::cout << TT::member_var << std::endl;
std::cout << TT::do_something() << std::endl;
}
int main()
{
function<SELECTOR1>();
function<SELECTOR2>();
return 0;
}
I'm not sure how to create "generic" algorithms this when dealing with polymorphic classes.
For example: https://onlinegdb.com/S1hFLGC7V
Below I have created an inherited class hierarchy. In this example I have a base catch-all example that defaults all the parameters to something (0 in this case). And then each derived class sets overrides specific methods.
#include <iostream>
#include <memory>
#include <type_traits>
#include <assert.h>
using namespace std;
struct Base {
virtual int get_thing_one() {
return 0;
}
virtual int get_thing_two() {
return 0;
}
virtual int get_thing_three() {
return 0;
}
virtual int get_thing_four() {
return 0;
}
};
struct A : public Base {
virtual int get_thing_one() override {
return 1;
}
virtual int get_thing_three() override {
return 3;
}
};
struct B : public Base {
virtual int get_thing_one() override {
return 2;
}
virtual int get_thing_four() override{
return 4;
}
};
Here I created a simple factory, not elegant but for illustrative purposes
// example simple factory
std::shared_ptr<Base> get_class(const int input) {
switch(input)
{
case 0:
return std::shared_ptr<Base>(std::make_shared<A>());
break;
case 1:
return std::shared_ptr<Base>(std::make_shared<B>());
break;
default:
assert(false);
break;
}
}
So this is the class of interest. It is a class does "something" with the data from the classes above. The methods below are a simple addition example but imagine a more complicated algorithm that is very similar for every method.
// class that uses the shared_ptr
class setter {
private:
std::shared_ptr<Base> l_ptr;
public:
setter(const std::shared_ptr<Base>& input):l_ptr(input)
{}
int get_thing_a()
{
return l_ptr->get_thing_one() + l_ptr->get_thing_two();
}
int get_thing_b()
{
return l_ptr->get_thing_three() + l_ptr->get_thing_four();
}
};
int main()
{
constexpr int select = 0;
std::shared_ptr<Base> example = get_class(select);
setter l_setter(example);
std::cout << l_setter.get_thing_a() << std::endl;
std::cout << l_setter.get_thing_b() << std::endl;
return 0;
}
How can I make the "boilerplate" inside the setter class more generic? I can't use traits as I did in the example above because I can't tie static functions with an object. So is there a way to make the boilerplate example more common?
Somewhere along the lines of having a selector, say
enum thing_select { THINGA, THINGB, };
template < thing_select T >
struct thing_traits;
template <>
struct thing_traits<THINGA>
{
static int first_function() --> somehow tied to shared_ptr<Base> 'thing_one' method
static int second_function() --> somehow tied to shared_ptr<Base> 'thing_two' method
}
template <>
struct thing_traits<THINGB>
{
static int first_function() --> somehow tied to shared_ptr<Base> 'thing_three' method
static int second_function() --> somehow tied to shared_ptr<Base> 'thing_four' method
}
// generic function I'd like to create
template < thing_select T, typename TT = thing_traits<T> >
int perform_action(...)
{
return TT::first_function(..) + TT::second_function(..);
}
I ideally would like to modify the class above to something along the lines of
// Inside setter class further above
int get_thing_a()
{
return perform_action<THINGA>(...);
}
int get_thing_b()
{
return perform_action<THINGB>(...);
}
The answer is, maybe I can't, and I need to pass int the shared_ptr as a parameter and call the specific methods I need instead of trying to tie a shared_ptr method to a static function (in hindsight, that doesn't sound like a good idea...but I wanted to bounce my idea)
Whoever makes the actual call will need a reference of the object, one way or the other. Therefore, assuming you want perform_action to perform the actual call, you will have to pass the parameter.
Now, if you really want to store which function of Base to call as a static in thing_traits without passing a parameter, you can leverage pointer to member functions:
template <>
struct thing_traits<THINGA>
{
static constexpr int (Base::*first_function)() = &Base::get_thing_one;
...
}
template < thing_select T, typename TT = thing_traits<T>>
int perform_action(Base & b)
{
return (b.*TT::first_function)() + ...;
}
You can also play instead with returning a function object that does the call for you (and the inner function takes the parameter).
It all depends on who you need to make the call and what information/dependencies you assume you have available in each class/template.
The following program which is supposed to emulate std::vector. I am using Eclipse IDE for C/C++ Developers
Version: Neon.3 Release (4.6.3)
Build id: 20170314-1500
and my c++ version is g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
is flagging error that "function std::move could not be resolved".
What is the possible reason for this error ?
//============================================================================
// Name : data_structure_1.cpp
// Author : Manish Sharma
// Description : Programme to implement a simple vector class named "Vector".
// Reference : Data Structures and Algo. analysis in c++, Mark Allen Weiss
//============================================================================
#include <iostream>
#include <algorithm>
using namespace std;
template<class Object>
class Vector{
public:
// constructor
explicit Vector(int initSize = 0):
theSize{initSize},
theCapacity{initSize + SPARE_CAPACITY},
objects{new Object[theCapacity]}{
}
// copy constructor
Vector(const Vector& rhs):
theSize{rhs.theSize},
theCapacity{rhs.theCapacity},
objects{new Object[theCapacity]}{
for(int k = 0;k<theSize; ++k){
objects[k] = rhs.objects[k];
}
}
// copy assignment operaor
Vector & operator= (const Vector & rhs){
Vector copy = rhs;
std::swap(*this,copy);
return *this;
}
//class destructor
~Vector(){
delete[] objects;
}
//c++ 11 additions, reference to rvalues
Vector(Vector&& rhs) :
theSize{rhs.theSize},
theCapacity{rhs.theCapacity},
objects{rhs.objects}{
cout<<endl<<"Inside lvalue reference constructor";
//if you forget to include this then when rhs will you destroyed
//you will be left with a dangling pointer
rhs.objects = nullptr;
rhs.theSize = 0;
rhs.theCapacity = 0;
}
// copy assignment operaor
Vector & operator= (Vector && rhs){
cout<<endl<<"Inside lvalue reference copy";
Vector copy = rhs;
std::swap(*this,copy);
return *this;
}
void resize(int newSize){
if(newSize > theCapacity)
reserve(newSize*2);
theSize = newSize;
}
void reserve(int newCapacity){
if(newCapacity<theSize)
return;
Object *newArray = new Object[newCapacity];
cout<<endl<<"moving inside reserve";
for(int k=0;k<theSize;++k){
newArray[k] = std::move(objects[k]);
}
theCapacity = newCapacity;
std::swap(objects,newArray);
delete[] newArray;
}
//Some extra useful functions
int size() const{
return theSize;
}
bool empty() const{
return size()==0;
}
int capacity() const{
return theCapacity;
}
void increaseCapacity(){
reserve(2*theCapacity+1);
}
//insertion and deletion functions
void push_back(const Object & x){
if(theSize == theCapacity){
increaseCapacity();
}
cout<<endl<<"Moving inside push_back";
objects[theSize++] = std::move(x);
}
void pop_back(){
--theSize;
}
using iterator = Object*;
using const_iterator = const Object*;
iterator begin(){
return &objects[0];
}
const_iterator begin() const{
return &objects[0];
}
iterator end(){
return &objects[size()];
}
const_iterator end() const{
return &objects[size()];
}
//class specific constants
static const int SPARE_CAPACITY = 16;
private:
int theSize;
int theCapacity;
Object * objects;
};
int main() {
Vector<int> my_vector;
my_vector.push_back(10);
int j{24};
my_vector.push_back(j);
for(int i = 0;i<20;i++){
my_vector.push_back(i*10);
}
cout<<"\nSize = "<<my_vector.size()<<endl;
my_vector.capacity();
for(auto it = my_vector.begin();it!=my_vector.end();++it){
cout<<*it<<", ";
}
return 0;
}
If I have two classes D1 and D2 that both derive from class Base, and I want to construct a particular one based on say, a boolean variable, there are various well known techniques, eg use a factory, or use smart pointers.
For example,
std::unique_ptr<Base> b;
if (flag)
{
b.reset(new D1());
}
else
{
b.reset(new D2());
}
But this uses the heap for allocation, which is normally fine but I can think of times where it would be good to avoid the performance hit of a memory allocation.
I tried:
Base b = flag ? D1() : D2(); // doesn’t compile
Base& b = flag ? D1() : D2(); // doesn’t compile
Base&& b = flag ? D1() : D2(); // doesn’t compile
Base&& b = flag ? std::move(D1()) : std::move(D2()); // doesn’t compile
My intention is that D1 or D2 whichever is chosen is constructed on the stack, and its lifetime ends when b goes out of scope. Intuitively, I feel there should be a way to do it.
I played with lambda functions and found that this works:
Base&& b = [j]()->Base&&{
switch (j)
{
case 0:
return std::move(D1());
default:
return std::move(D2());
}
}();
Why it doesn’t suffer from the same issues as the others that do not compile I do not know.
Further, it would only be suitable for classes that are inexpensive to copy, because despite my explicit request to use move, it does I think still call a copy constructor. But if I take away the std::move, I get a warning!
I feel this is closer to what i think should be possible but it still has some issues:
the lambda syntax is not friendly to old-timers who havent yet
embraced the new features of the language ( myself included)
the copy constructor call as mentioned
Is there a better way of doing this?
If you know all the types, you can use a Boost.Variant, as in:
class Manager
{
using variant_type = boost::variant<Derived1, Derived2>;
struct NameVisitor : boost::static_visitor<const char*>
{
template<typename T>
result_type operator()(T& t) const { return t.name(); }
};
public:
template<typename T>
explicit Manager(T t) : v_(std::move(t)) {}
template<typename T>
Manager& operator=(T t)
{ v_ = std::move(t); return *this; }
const char* name()
{ return boost::apply_visitor(NameVisitor(), v_); }
private:
variant_type v_;
};
Note: by using variant, you no longer need a base class or virtual functions.
The way you are trying to do it, you are going to get a dangling reference. Having the std::move is just hiding that.
Generally I just structure the code so that the logic is in a separate function. That is, instead of
void f(bool flag)
{
Base &b = // some magic to choose which derived class to instantiate
// do something with b
}
I do
void doSomethingWith(Base &b)
{
// do something with b
}
void f(bool flag)
{
if (flag) {
D1 d1;
doSomethingWith(d1);
}
else {
D2 d2;
doSomethingWith(d2);
}
}
However, if that doesn't work for you, you can use a union inside a class to help manage it:
#include <iostream>
using std::cerr;
struct Base {
virtual ~Base() { }
virtual const char* name() = 0;
};
struct Derived1 : Base {
Derived1() { cerr << "Constructing Derived1\n"; }
~Derived1() { cerr << "Destructing Derived1\n"; }
virtual const char* name() { return "Derived1"; }
};
struct Derived2 : Base {
Derived2() { cerr << "Constructing Derived2\n"; }
~Derived2() { cerr << "Destructing Derived2\n"; }
virtual const char* name() { return "Derived2"; }
};
template <typename B,typename D1,typename D2>
class Either {
union D {
D1 d1;
D2 d2;
D() { }
~D() { }
} d;
bool flag;
public:
Either(bool flag)
: flag(flag)
{
if (flag) {
new (&d.d1) D1;
}
else {
new (&d.d2) D2;
}
}
~Either()
{
if (flag) {
d.d1.~D1();
}
else {
d.d2.~D2();
}
}
B& value()
{
if (flag) {
return d.d1;
}
else {
return d.d2;
}
}
};
static void test(bool flag)
{
Either<Base,Derived1,Derived2> either(flag);
Base &b = either.value();
cerr << "name=" << b.name() << "\n";
}
int main()
{
test(true);
test(false);
}
gives this output:
Constructing Derived1
name=Derived1
Destructing Derived1
Constructing Derived2
name=Derived2
Destructing Derived2
You can ensure you have enough space for allocating either on the stack with std::aligned_storage. Something like:
// use macros for MAX since std::max is not const-expr
std::aligned_storage<MAX(sizeof(D1), sizeof(D2)), MAX(alignof(D1), alignof(D2))> storage;
Base* b = nullptr;
if (flag)
b = new (&storage) D1();
else
b = new (&storage) D2();
You can make a wrapper type for aligned_storage that just takes two types and does the maximum of size/alignment of the two without needing to repeat yourself in the code using it. You can emulate aligned_storage for non-over-aligned types fairly trivially too if you need C++98 support. The custom type without over-aligned support would be something like:
template <typename T1, typename T2>
class storage
{
union
{
double d; // to force strictest alignment (on most platforms)
char b[sizeof(T1) > sizeof(T2) ? sizeof(T1) : sizeof(T2)];
} u;
};
And that can be given protections against copies/moves if you so wish. It can even be turned into a simplified Boost.Variant with relatively little work.
Note that with this approach (or some of the others), destructors will not be called automatically on your class and you must call them yourself. If you want RAII patterns to apply here, you can extend the example class above to store a deleter function that is bound during construction into the space.
template <typename T1, typename T2>
class storage
{
using deleter_t = void(*)(void*);
std::aligned_storage<
sizeof(T1) > sizeof(T2) ? sizeof(T1) : sizeof(T2),
alignof(T1) > alignof(T2) ? alignof(T1) : alignof(T2)
> space;
deleter_t deleter = nullptr;
public:
storage(const storage&) = delete;
storage& operator=(const storage&) = delete;
template <typename T, typename ...P>
T* emplace(P&&... p)
{
destroy();
deleter = [](void* obj){ static_cast<T*>(obj)->~T(); }
return new (&space) T(std::forward<P>(p)...);
}
void destroy()
{
if (deleter != nullptr)
{
deleter(&space);
deleter = nullptr;
}
}
};
// usage:
storage<D1, D2> s;
B* b = flag ? s.emplace<D1>() : s.emplace<D2>();
And of course that can all be done in C++98, just with a lot more work (especially in terms of emulating the emplace function).
How about
B&&b = flag ? static_cast<B&&>(D1()) : static_cast<B&&>(D2());
If you just need them to be freed when the reference goes out of scope, you could implement another simple class (maybe named DestructorDecorator) that points to the object (D1 or D2). And then you just have to implement ~DestructorDecorator to call the destructor of D1 or D2.
You haven't mentioned it, your flag is known at compile time?
As far as a compile-time flag is concerned, you can use template magic to deal with the conditional construction of the class:
First, declaring a template create_if which takes two types and a boolean:
template <typename T, typename F, bool B> struct create_if {};
Second, specializing create_if for true and false values:
template <typename T, typename F> struct create_if<T, F, true> { using type = T; };
template <typename T, typename F> struct create_if<T, F, false> { using type = F; };
Then, you can do this:
create_if<D1, D2, true>::type da; // Create D1 instance
create_if<D1, D2, false>::type db; // Create D2 instance
You can change the boolean literals with your compile-time flag or with a constexpr function:
constexpr bool foo(const int i) { return i & 1; }
create_if<D1, D2, foo(100)>::type dc; // Create D2 instance
create_if<D1, D2, foo(543)>::type dd; // Create D1 instance
This is valid only if the flag is known at compile time, I hope it helps.
Live example.
Would the following be an idiomatic C++11 implementation of a Scope Guard that restores a value upon scope exit?
template<typename T>
class ValueScopeGuard
{
public:
template<typename U>
ValueScopeGuard(T& value, U&& newValue):
_valuePtr(&value),
_oldValue(std::forward<U>(newValue))
{
using std::swap;
swap(*_valuePtr, _oldValue);
}
~ValueScopeGuard()
{
if(_valuePtr)
{
using std::swap;
swap(*_valuePtr, _oldValue);
}
}
// Copy
ValueScopeGuard(ValueScopeGuard const& other) = delete;
ValueScopeGuard& operator=(ValueScopeGuard const& other) = delete;
// Move
ValueScopeGuard(ValueScopeGuard&& other):
_valuePtr(nullptr)
{
swap(*this, other);
}
ValueScopeGuard& operator=(ValueScopeGuard&& other)
{
ValueScopeGuard(std::move(other)).swap(*this);
return *this;
}
private:
T* _valuePtr;
T _oldValue;
friend void swap(ValueScopeGuard& lhs, ValueScopeGuard& rhs)
{
using std::swap;
swap(lhs._valuePtr, rhs._valuePtr);
swap(lhs._oldValue, rhs._oldValue);
}
};
template<typename T, typename U>
ValueScopeGuard<T> makeValueScopeGuard(T& value, U&& newValue)
{
return {value, std::forward<U>(newValue)};
}
It could be used to temporarily change a value as follows:
int main(int argc, char* argv[])
{
// Value Type
int i = 0;
{
auto guard = makeValueScopeGuard(i, 1);
std::cout << i << std::endl; // 1
}
std::cout << i << std::endl; // 0
// Movable Type
std::unique_ptr<int> a{new int(0)};
{
auto guard = makeValueScopeGuard(a, std::unique_ptr<int>{new int(1)});
std::cout << *a << std::endl; // 1
}
std::cout << *a << std::endl; // 0
return 0;
}
Is a simple utility like this already implemented in a library somewhere? I had a look at Boost.ScopeExit, but its intended usage seems different and more complex.
Assuming makeValueScopeGuard to be implemented as :
template< typename T >
ValueScopeGuard<T> makeValueScopeGuard( T& t, T&& v )
{
return ValueScopeGuard<T>(t,std::move(v));
}
no, it is not very good implementation of scope guard, because it is going to fail when you pass l-values as the 2nd parameter :
int kk=1;
auto guard = makeValueScopeGuard(i, kk);
The second problem is that you used std::forward, when you should have used std::move.
As this question and answers show, people are usually using lambdas to implement scope guard.
Your move constructor leaves the pointer member uninitialized, so the rvalue object ends up holding a junk pointer, which it dereferences in its destructor. That's a bug. You should initialize it to nullptr and check for nullptr in the destructor.
For a type like this I would not expect move assignment to be a simple swap, I would expect the rvalue to end up not owning anything. So I would implement the move like this instead, so the rvalue ends up empty:
ValueScopeGuard& operator=(ValueScopeGuard&& other)
{
ValueScopeGuard(std::move(other)).swap(*this);
return *this;
}
The name makeValueScopeGuard isn't clear to me that it changes the value itself, I'd expect it to just copy the current value and restore it in the destructor.
As far as existing types go, the closest I can think of is the Boost I/O state savers, which do not alter the current state they just copy it and restore it.