Change the class of an object: possible with std::move? - c++

I know that I cannot mess with the V-Table (in a somewhat sane way) once an object is created. Which means I have to copy an object to change it's type. Does this also hold true with c++11's std::move and friends?
class Base {
public:
virtual int type() = 0;
// more data members I want to avoid to copy
};
class D1 : public Base {
public:
int type() {
return 1;
}
};
class D2 : public D1 {
public:
int type() {
return 2;
}
};
int main()
{
// creating the actual object, type is D1
D1* obj = new D1();
// this is what does not work, I want to "change" the object to D2
D2* obj2 = &std::move<D2>(*obj);
// cast it to obj2 base class
Base* baseObj = static_cast<D1*>(obj2);
// now I want a "2" here
int t = baseObj->type();
printf ("%d\n", t);
}
I do not know the move semantics very well... But is there something I can change a D1 object into D2 (or vice versa) with type safety? (Both classes are virtually the same from the memory layout)

While you cannot change the type of an existing object, you can easily change the dynamic type of a pointer member and achieve the desired effect. This is known as strategy design pattern.
E.g.:
#include <memory>
#include <iostream>
class Host
{
struct Strategy
{
virtual ~Strategy() = default;
virtual int type() const = 0;
};
struct StrategyA : Strategy { int type() const override { return 1; } };
struct StrategyB : Strategy { int type() const override { return 2; } };
std::unique_ptr<Strategy> strategy_;
public:
Host()
: strategy_(new StrategyA)
{}
int type() const { return strategy_->type(); }
void change_strategy(int type) {
switch(type) {
case 1: strategy_.reset(new StrategyA); break;
case 2: strategy_.reset(new StrategyB); break;
default: std::abort();
}
}
};
int main() {
Host host;
std::cout << host.type() << '\n';
host.change_strategy(2);
std::cout << host.type() << '\n';
}

It seems to me you are not familiar with what std::move actually does.
As others have said, std::move doesn't actually move anything. It obtains an xvalue (a variable that has a name, but can have its resources reused or transfered to another object) reference from an lvalue (essentially a named variable), so, std::move is nothing but a cast. It doesn't create any new object. Read more about it here and here.
Still about move semantics topic,
std::move is mostly useful so that you can force rvalue-aware methods to receive and reuse resources in variables that you absolutely know that can have their resources moved.
To get a more indepth insight of this, I'd recommend reading What are move semantics?. For instance, one of its uses is creating an object from a temporary (e.g, objects created inside a function and then returned):
#include <vector>
#include <iostream>
class A {
public:
// A very large resource
std::vector<int> resource;
// Constructs our very large resource
A(): resource(1024, 0) { std::cout << "Default construct" << std::endl; }
// Move (reuses) a very large resource from an instance
A(A && other) : resource(std::move(other.resource)) {
std::cout << "Move construct" << std::endl;
}
};
Now, A's move constructor is only called when the other object is an rvalue (or an xvalue), such as:
A foo(A a) { return a; }
int main() {
A a = foo(A());
return 0
}
In this scenario, before foo() gets called, a temporary A() is created and passed in as argument. foo() returns it, but since it is a temporary , it fits as an rvalue and is passed to the move constructor of A when constructing A a = foo(A()).
Inside the move constructor of A(), std::move(other.resource) is used when constructing another resource to call the move constructor of std::vector so that it can try to use whatever it can from other.resource instead of creating everything from scratch again (and then copying).
But as stated previously, std::move on itself doesn't move anything, but it is there to convey intent to move, help the compiler do the right thing (and other programmers to read it and understand faster what you meant).
So, to answer your question directly, no, there isn't anything that'd let you transform an object into another, other than constructing a new object. If you are sure that you are going to destroy obj (which you are not doing, by the way), you can implement an constructor of D2 that accepts an rvalue of D1:
class D2 {
public:
D2(D1 && d1) : resource(std::move(d1.resource)) { d1.resource = nullptr; }
}
int main() {
D1 * obj = new D1();
D2 * obj2 = new D2(std::move(*obj));
delete obj;
}
There are other things to consider when doing this, though, such as destructors of moved objects and other details. I'd recommend reading more about the subject and also maybe using a different method of achieving what you are doing, such as the Strategy pattern mentioned in another answer.

Related

C++ casting a derived subclass into another derived subclass

So what I'm trying to achieve here is casting a derived subclass into another subclass derived from the same subclass. This far it's looking like it's not possible to actually be done but I'm still believing.
My example code is:
#include <iostream>
#include <vector>
class BaseClass
{
public:
virtual void printFunction() = 0;
};
class printOne : public BaseClass
{
public:
void printFunction() override
{
std::cout << "One\n";
}
};
class printTwo : public BaseClass
{
public:
void printFunction() override
{
std::cout << "Two\n";
}
};
int main()
{
std::vector<BaseClass *> baseClassVector;
printOne * one = new printOne;
baseClassVector.push_back(one);
printTwo * two = new printTwo;
baseClassVector.push_back(two);
}
So what i want to actually do here with this vector is that I want to change the "one" object on index zero, to a "two" object. Now this can be done through the code
delete baseClassVector[0];
printTwo * two = new printTwo;
baseClassVector[0] = two;
However as far as I know, this is extremely costly, especially if it has to be done at runtime. I was wondering if there's another way to go about doing this or if the costs are worth it compared to other alternatives.
Thanks in advance!
With the simplified example in the question, use a std::variant which is simpler and just avoid the base class altogether:
class printOne
{
public:
void printFunction() const
{
std::cout << "One\n";
}
};
class printTwo
{
public:
void printFunction() const
{
std::cout << "Two\n";
}
};
using printEither = std::variant<printOne, printTwo>;
void printFunction(const printEither& e)
{
std::visit([](auto& p) { p.printFunction(); }, e);
}
int main()
{
std::vector<printEither> eitherVector;
printOne one;
eitherVector.push_back(one);
printTwo two;
eitherVector.push_back(two);
eitherVector[0] = two;
for (auto& e: eitherVector)
printFunction(e);
}
Re-using an allocation for effectively unrelated types in C++ is a pain to write correctly. It is easier and preferable to incur an allocation.
It is technically possible to "rebuild" an object in place as a different type, though the following should be taken as just a proof of concept, not a recommendation for design or practice. First price to pay is giving up the convenience of new/delete for manually managed placement new and explicit destructors used with malloc/free.
const size_t sz = max(sizeof(printOne), sizeof(printTwo));
BaseClass *either = (BaseClass *)malloc(sz); // allocate memory for objects
new(either) printOne(); // construct printOne object
printOne *one = dynamic_cast<printOne *>(either); // ... use printOne object
one->~printOne(); // destruct printOne object
new(either) printTwo(); // construct printTwo object
printTwo *two = dynamic_cast<printTwo *>(either); // ... use printTwo object
two->~printTwo(); // destruct printTwo object
free(either); // free memory used by objects

How to limit to stack allocations for polymorphic solution of resolving types [duplicate]

How do I allocate a polymorphic object on the stack? I'm trying to do something similar to (trying to avoid heap allocation with new)?:
A* a = NULL;
switch (some_var)
{
case 1:
a = A();
break;
case 2:
a = B(); // B is derived from A
break;
default:
a = C(); // C is derived from A
break;
}
You can't structure a single function to work like that, since automatic or temporary objects created inside a conditional block can't have their lifetimes extended into the containing block.
I'd suggest refactoring the polymorphic behaviour into a separate function:
void do_something(A&&);
switch (some_var)
{
case 1:
do_something(A());
break;
case 2:
do_something(B()); // B is derived from A
break;
default:
do_something(C()); // C is derived from A
break;
}
Disclaimer: I definitely don't think this is a good solution. The good solutions are to either rethink the design (maybe OO polymorphism is not warranted here given that there is a bounded number of possibilities?), or to use a second function to pass along said polymorphic object by reference.
But since other folks mentioned this idea, but got details wrong, I'm posting this answer to show how to get it right. Hopefully I get it right.
It is clear the the number of possible types is bounded. This means that a discriminated union, like boost::variant could solve the problem, even if it's not pretty:
boost::variant<A, B, C> thingy =
some_var == 1? static_cast<A&&>(A())
: some_var == 2? static_cast<A&&>(B())
: static_cast<A&&>(C());
The fact that now you can use things like static visitors is one if the things that keeps making me think this isn't a good use of OO polymorphism.
If instead of a ready-made solution, you want to use placement new by hand as suggested in other answers, there are a number of things that need care because we lose some of the properties of regular automatic objects in the process:
the compiler no longer gives us the right size and alignment;
we no longer get an automatic call to the destructors;
In C++11, these are both easy to fix with aligned_union and unique_ptr, respectively.
std::aligned_union<A, B, C>::type thingy;
A* ptr;
switch (some_var)
{
case 1:
ptr = ::new(&thingy.a) A();
break;
case 2:
ptr = ::new(&thingy.b) B();
break;
default:
ptr = ::new(&thingy.c) C();
break;
}
std::unique_ptr<A, void(*)(A*)> guard { ptr, [](A* a) { a->~A(); } };
// all this mechanism is a great candidate for encapsulation in a class of its own
// but boost::variant already exists, so...
For compilers that don't support these features, you can get alternatives: Boost includes aligned_storage and alignment_of traits which can be used to build aligned_union; and unique_ptr can be replaced with some kind of scope guard class.
Now that that is out of the way, just so it's clear, don't do this and simply pass a temporary along to another function, or revisit the design altogether.
If B is your base types D1, D2, and D3 are your derived types:
void foo()
{
D1 derived_object1;
D2 derived_object2;
D3 derived_object3;
B *base_pointer;
switch (some_var)
{
case 1: base_pointer = &derived_object1; break;
....
}
}
If you want to avoid wasting the space of the three derived objects, you could break up your method into two parts; the part that chooses which type you need, and the part of the method that works on it. Having decided which type you need, you call a method that allocates that object, creates a pointer to it, and calls the second half of the method to complete the work on the stack-allocated object.
I wrote a generic template to do it. Full code available here (it became too elaborate for the scope of this question).
StackVariant object contains a buffer of the size of the biggest type out of the provided types, and biggest alignment as well. The Object is constructed on the stack using a 'placement new' and operator->() is used for polymorphic access to suggest the indirection. Also, it is important to make sure that if a virtual detor is defined, it should be called upon destruction of the object on the stack, so the template detor is doing just that using a SFINAE definition.
(see usage example and output below):
// compile: g++ file.cpp -std=c++11
#include <type_traits>
#include <cstddef>
// union_size()/union_align() implementation in gist link above
template<class Tbaseclass, typename...classes>
class StackVariant {
alignas(union_align<classes...>()) char storage[union_size<classes...>()];
public:
inline Tbaseclass* operator->() { return ((Tbaseclass*)storage); }
template<class C, typename...TCtor_params>
StackVariant& init(TCtor_params&&...fargs)
{
new (storage) C(std::forward<TCtor_params>(fargs)...); // "placement new"
return *this;
};
template<class X=Tbaseclass>
typename std::enable_if<std::has_virtual_destructor<X>::value, void>::type
call_dtor(){
((X*)storage)->~X();
}
template<class X=Tbaseclass>
typename std::enable_if<!std::has_virtual_destructor<X>::value, void>::type
call_dtor() {};
~StackVariant() {
call_dtor();
}
};
Usage example:
#include <cstring>
#include <iostream>
#include "StackVariant.h"
class Animal{
public:
virtual void makeSound() = 0;
virtual std::string name() = 0;
virtual ~Animal() = default;
};
class Dog : public Animal{
public:
void makeSound() final { std::cout << "woff" << std::endl; };
std::string name() final { return "dog"; };
Dog(){};
~Dog() {std::cout << "woff bye!" << std::endl;}
};
class Cat : public Animal{
std::string catname;
public:
Cat() : catname("gonzo") {};
Cat(const std::string& _name) : catname(_name) {};
void makeSound() final { std::cout << "meow" << std::endl; };
std::string name() final { return catname; };
};
using StackAnimal = StackVariant<Animal, Dog, Cat>;
int main() {
StackAnimal a1;
StackAnimal a2;
a1.init<Cat>("gonzo2");
a2.init<Dog>();
a1->makeSound();
a2->makeSound();
return 0;
}
// Output:
// meow
// woff
// woff bye!
Few things to note:
I wrote it while trying to avoid heap allocations in performance critical functions and it did the job - 50% speed gains.
I wrote it to utilize C++'s own polymorphic mechanisms. Before that my code was full of switch-cases like the previous suggestions here.
You can't create a polymorphic local variable
You can't create a polymorphic local variable, since a subclass B of A might have more attributes than A, thus take more place, so the compiler would have to reserve enough space for the largest subclass of A.
In case you have dozens of subclasses, and one of them has a large number of attributes, this would waste a lot of space.
In case you put in the local variable an instance of a subclass of A you received as a parameter, and you put your code in a dynamic library, then the code linking with it could declare a subclass larger than those in your library, so the compiler wouldn't have allocated enough space on the stack anyway.
So allocate space for it yourself
Using placement new, you can initialize the object in a space you allocated through some other means:
alloca, but seeing this SO question it seems it's not the best option.
A Variable Length Array, with which comes some (non-)portability fun, since it works under GCC but isn't in the C++ standard (not even in C++11)
aligned_union<A, B, C>::type, as suggested by R. Martinho Fernandes in a comment to this answer
However, these techniques may use a lot of extra space, and don't work if you are given a reference (pointer) to an unknown-at-compile-time subclass of A that is larger than the types you accounted for.
The solution I propose is to have a kind of factory method on each subclass, that calls a supplied function with a pointer to a stack-allocated instance of the given subclass. I added an extra void* parameter to the supplied function's signature, so one can pass it arbitrary data.
#MooingDuck suggested this implementation using templates and C++11 in a comment below. In case you need this for code that can't benefit from C++11 features, or for some plain C code with structs instead of classes (if struct B has a first field of type struct A, then it can be manipulated somewhat like a "substruct" of A), then my version below will do the trick (but without being type-safe).
This version works with newly defined subclasses, as long as they implement the ugly factory-like method, and it will use a constant amount of stack for the return address and other informations required by this intermediate function, plus the size of an instance of the requested class, but not the size of the largest subclass (unless you choose to use that one).
#include <iostream>
class A {
public:
int fieldA;
static void* ugly(void* (*f)(A*, void*), void* param) {
A instance;
return f(&instance, param);
}
// ...
};
class B : public A {
public:
int fieldB;
static void* ugly(void* (*f)(A*, void*), void* param) {
B instance;
return f(&instance, param);
}
// ...
};
class C : public B {
public:
int fieldC;
static void* ugly(void* (*f)(A*, void*), void* param) {
C instance;
return f(&instance, param);
}
// ...
};
void* doWork(A* abc, void* param) {
abc->fieldA = (int)param;
if ((int)param == 4) {
((C*)abc)->fieldC++;
}
return (void*)abc->fieldA;
}
void* otherWork(A* abc, void* param) {
// Do something with abc
return (void*)(((int)param)/2);
}
int main() {
std::cout << (int)A::ugly(doWork, (void*)3);
std::cout << (int)B::ugly(doWork, (void*)1);
std::cout << (int)C::ugly(doWork, (void*)4);
std::cout << (int)A::ugly(otherWork, (void*)2);
std::cout << (int)C::ugly(otherWork, (void*)11);
std::cout << (int)B::ugly(otherWork, (void*)19);
std::cout << std::endl;
return 0;
}
By then, I think we might have outweighed the costs of a simple malloc, so you might wand to use that after all.
You can do it with placement new. This will place the items on the stack, in the memory contained in the buffer. However, these variables are not automatic. The downside is that your destructors won't run automatically, you would need to properly destruct them just as you've created them when they go out of scope.
A reasonable alternative to manually calling the destructor is to wrap your type in a smart pointer, as shown below:
class A
{
public:
virtual ~A() {}
};
class B : public A {};
class C : public B {};
template<class T>
class JustDestruct
{
public:
void operator()(const T* a)
{
a->T::~T();
}
};
void create(int x)
{
char buff[1024] // ensure that this is large enough to hold your "biggest" object
std::unique_ptr<A, JustDestruct<T>> t(buff);
switch(x)
{
case 0:
ptr = new (buff) A();
break;
case 1:
ptr = new (buff) B();
break;
case 2:
ptr = new (buff) C();
break;
}
// do polymorphic stuff
}
Polymorphism doesn't work with values, you need a reference or a pointer. You can use a const reference to a temporary object polymorphically and it will have the lifetime of a stack object.
const A& = (use_b ? B() : A());
If you need to modify the object, you have no choice but to dynamically allocate it (unless you're using Microsoft's non-standard extension that lets you bind a temporary object to a non-const reference).
A combination of a char array and placement new would work.
char buf[<size big enough to hold largest derived type>];
A *a = NULL;
switch (some_var)
{
case 1:
a = new(buf) A;
break;
case 2:
a = new(buf) B;
break;
default:
a = new(buf) C;
break;
}
// do stuff with a
a->~A(); // must call destructor explicitly
To strictly answer your question - what you have now does just that - i.e. a = A(); and a = B() and a = C(), but these objects are sliced.
To achieve polymorphic behavior with the code you have, I', afraid that's not possible. The compiler needs to know the size beforehand of the object. Unless you have references or pointers.
If you use a pointer, you need to make sure it doesn't end up dangling:
A* a = NULL;
switch (some_var)
{
case 1:
A obj;
a = &obj;
break;
}
won't work because obj goes out of scope. So you're left with:
A* a = NULL;
A obj1;
B obj2;
C obj3;
switch (some_var)
{
case 1:
a = &obj1;
break;
case 2:
a = &obj2;
break;
case 3:
a = &obj3;
break;
}
This of course is wasteful.
For references it's a bit trickier because they have to be assigned on creation, and you can't use temporaries (unless it's a const reference). So you'll probably need a factory that returns a persistent reference.
trying to avoid heap allocation with new)?
Well in that case you create object on stack as usual and assign address to the base pointer. But remember, if this is done inside a function, don't pass the address as return value, because stack will unwind after the function call returns.
So this is bad.
A* SomeMethod()
{
B b;
A* a = &b; // B inherits from A
return a;
}
It is possible, but it's a lot of effort to do cleanly (without manual placement new and exposed raw buffers, that is).
You're looking at something like Boost.Variant, modified to restrict the types to a base class and some derived classes, and to expose a polymorphic reference to the base type.
This thing (PolymorphicVariant ?) would wrap all the placement new stuff for you (and also take care of safe destruction).
If it's really what you want, let me know and I'll give you a start. Unless you really need exactly this behaviour though, Mike Seymour's suggestion is more practical.
Run this short program and you'll see why polymorphic objects do not work on the stack very well. When you create a stack object of a derived type that is unknown and expect it to be returned from a function call, what happens is the object is destroyed when that calling function goes out of scope. Thus the object only lives as long as that function is within scope. In order to return a valid object that will outlive the calling function you need to use the heap. This is demonstrated with this simple hierarchy and two versions of the same function with a switch statement except one does the stack and the other does it on the heap. Look at the output from both implementations and look to see what methods are called, what class they are being called from and when they are being called.
#include <string>
#include <iostream>
class Base {
public:
enum Type {
DERIVED_A = 0,
DERIVED_B,
DERIVED_C
};
protected:
Type type_;
public:
explicit Base(Type type) : type_(type) {
std::cout << "Base Constructor Called." << std::endl;
}
virtual ~Base() {
std::cout << "Base Destructor Called." << std::endl;
}
virtual void doSomething() {
std::cout << "This should be overridden by derived class without making this a purely virtual method." << std::endl;
}
Type getType() const { return type_; }
};
class DerivedA : public Base {
public:
DerivedA() : Base(DERIVED_A) {
std::cout << "DerivedA Constructor Called." << std::endl;
}
virtual ~DerivedA() {
std::cout << "DerivedA Destructor Called." << std::endl;
}
void doSomething() override {
std::cout << "DerivedA overridden this function." << std::endl;
}
};
class DerivedB : public Base {
public:
DerivedB() : Base(DERIVED_B) {
std::cout << "DerivedB Constructor Called." << std::endl;
}
virtual ~DerivedB() {
std::cout << "DerivedB Destructor Called." << std::endl;
}
void doSomething() override {
std::cout << "DerivedB overridden this function." << std::endl;
}
};
class DerivedC : public Base {
public:
DerivedC() : Base(DERIVED_C) {
std::cout << "DerivedC Constructor Called." << std::endl;
}
virtual ~DerivedC() {
std::cout << "DerivedC Destructor Called." << std::endl;
}
void doSomething() override {
std::cout << "DerivedC overridden this function." << std::endl;
}
};
Base* someFuncOnStack(Base::Type type) {
Base* pBase = nullptr;
switch (type) {
case Base::DERIVED_A: {
DerivedA a;
pBase = dynamic_cast<Base*>(&a);
break;
}
case Base::DERIVED_B: {
DerivedB b;
pBase = dynamic_cast<Base*>(&b);
break;
}
case Base::DERIVED_C: {
DerivedC c;
pBase = dynamic_cast<Base*>(&c);
break;
}
default: {
pBase = nullptr;
break;
}
}
return pBase;
}
Base* someFuncOnHeap(Base::Type type) {
Base* pBase = nullptr;
switch (type) {
case Base::DERIVED_A: {
DerivedA* pA = new DerivedA();
pBase = dynamic_cast<Base*>(pA);
break;
}
case Base::DERIVED_B: {
DerivedB* pB = new DerivedB();
pBase = dynamic_cast<Base*>(pB);
break;
}
case Base::DERIVED_C: {
DerivedC* pC = new DerivedC();
pBase = dynamic_cast<Base*>(pC);
break;
}
default: {
pBase = nullptr;
break;
}
}
return pBase;
}
int main() {
// Function With Stack Behavior
std::cout << "Stack Version:\n";
Base* pBase = nullptr;
pBase = someFuncOnStack(Base::DERIVED_B);
// Since the above function went out of scope the classes are on the stack
pBase->doSomething(); // Still Calls Base Class's doSomething
// If you need these classes to outlive the function from which they are in
// you will need to use heap allocation.
// Reset Base*
pBase = nullptr;
// Function With Heap Behavior
std::cout << "\nHeap Version:\n";
pBase = someFuncOnHeap(Base::DERIVED_C);
pBase->doSomething();
// Don't Forget to Delete this pointer
delete pBase;
pBase = nullptr;
char c;
std::cout << "\nPress any key to quit.\n";
std::cin >> c;
return 0;
}
Output:
Stack Version:
Base Constructor Called.
DerivedB Constructor Called.
DerivedB Destructor Called.
Base Destructor Called.
This should be overridden by derived class without making this a purely virtual method.
Heap Version:
Base Constructor Called.
DerivedC Constructor Called.
DerivedC overridden this function.
DerivedC Destructor called.
Base Destructor Called.
I'm not saying that it can not be done; I'm just stating the caveats in trying to do so. It may be ill-advised to try to do something of the sort. I do not know of any way to do this unless if you have a wrapper class that will contain the stack allocated objects to manage their life time. I'll have to try and work on that to see if I can come up with something of the sort.

getting all objects of a classes in C++

Is there a way through which we can get all the objects of a class in C++.Like in Python we can do
class_name.objects.all()
to get all the objects of a class.What's its analog in C++,if it exists?
You can do this yourself, but make sure you know what you're doing.
How:
There's nothing within C++ that already does this, but it's pretty easy to do this yourself. The key is to recognize that a class can have static member variables and functions (i.e. functions that belong to the whole class, rather than to individual objects of the class).
So you can use some kind of table or other data structure to store a reference to each object. Like so:
class A {
public:
//constructor assigns this object an id based on the static value curID,
//which is common to the class (i.e. the next class to call the constructor
//will be assigned an id thats 1 more than this one
//also, constructor adds the pointer to this object to a static map of ids
//to objects. This way, the map can be queried for the pointer to an object
//that has a particular id
A() {
id = curID++;
objects[id] = this;
}
//copy constructor ensures an object copied from another does not
//take the id of the other object, and gets added to the map
A(const A&) {
id = curID++; //don't want have the same ID as the object we are copying from
objects[id] = this;
x = A.x;
y = A.y;
}
A& operator=(const A&) {
id = curID++;
objects[id] = this;
x = A.x;
y = A.y;
return *this;
}
//destructor removes the pointer to this object from the map
~A() {
objects.erase(id);
}
//function to get the map that stores all the objects
static map<int, A*>& GetMapOfObjects() {
return objects;
}
private:
//the following variable is **static**, which means it does not
//belong to a single object but to the whole class. Here, it is
//used to generate a unique ID for every new object that's
//instantiated. If you have a lot of objects (e.g. more than
//32,767), consider using a long int
static int curID;
//this variable is also static, and is map that stores a pointer
//to each object. This way, you can access the pointer to a
//particular object using its ID. Depending on what you need, you
//could use other structures than a map
static map<int, A*> objects;
//this is a (non-static) member variable, i.e. unique to each object.
//Its value is determined in the constructor, making use of curID.
int id;
//these are some other member variables, depending on what your object actually is
double x;
double y;
}
Note: The above design is very basic and not complete, but just meant to give you an idea of how to implement what you're asking for using static members/functions. For example, for operations that you want to perform on all the objects, for example, it may be better to implement a static function that iterates through the map of elements, rather than getting the map and then doing the iterations "outside".
Why:
I've never used this method myself, but one potential use case I can think of is e.g. in a graphics or game application, where you may want to only draw objects that are in scope and change certain drawing-related properties of all of them at once, e.g. color or size. I'm working on an application that might eventually need something like this (sort of a visual debugger). I'm sure people can provide more examples in the comments.
Why not:
The picture gets complicated when inheritance is involved.
If you have a class B that derives from A (i.e. B "is an" A), then who should keep track of objects of B? A static member of objects in A, or a similar one in B, or both?
Let's say both. Then what happens if a static function that applies to all objects in A calls a virtual member function on each object? If the virtual function has been overridden in the derived class, then that function will be called instead for all objects being tracked in class A that are actually B objects. What happens if you then call that function again in another static function in B?
There is no way that I know of but you can implement one with static members
#include <iostream>
#include <vector>
class MyClass{
private:
static std::vector<MyClass*> objList;
public:
MyClass() {
objList.push_back(this);
}
static std::vector<MyClass*> getAllObjects(){
return objList;
}
};
std::vector<MyClass*> MyClass::objList;
main(){
MyClass m,a;
for (int i=0;i<MyClass::getAllObjects().size();i++){
std::cout<<MyClass::getAllObjects()[i]<<std::endl;
}
}
No, unless you implement this mechanism yourself. By default it is not provided by C++ language.
You CAN implement this mechanism yourself quite easily - register class in some kind of table within constructor, unregister within destructor. As long as you follow rule of Three, it'll work fine.
Of course there is. Just use Factory pattern to create and destroy all your objects and, in Factory implementation, return a collection of live objects in a Factory function that you will provide.
As has already been stated C++ does not provide a mechanism to do this automatically. However (again has already been stated in the comments) you can use one of the standard library containers to maintain a list of created objects and then register them in the constructor and unregister them in the destructor. The example below shows one way to do this...
#include <iostream>
#include <memory>
#include <utility>
#include <map>
#include <algorithm>
#include <iterator>
#include <typeinfo>
#include <vector>
class Object
{
static std::map<const Object*, Object*> objects_;
public:
Object()
{
objects_.insert(std::make_pair(this, this));
}
virtual ~Object()
{
objects_.erase(this);
}
static std::vector<Object*> get_all()
{
std::vector<Object*> o;
o.reserve(objects_.size());
for (auto obj : objects_)
{
o.push_back(obj.second);
}
return std::move(o);
}
template<class Type>
static std::vector<Type*> get_bytype()
{
std::vector<Type*> o;
for(auto obj : objects_)
{
Type *t = dynamic_cast<Type*>(obj.second);
if (t != nullptr)
{
o.push_back(t);
}
};
return std::move(o);
}
void print() const
{
std::cout << "I'm a " << typeid(*this).name() << " object # " << this << std::endl;
}
};
std::map<const Object*, Object*> Object::objects_;
class Foo : public Object {};
class Bar : public Object {};
int main()
{
std::unique_ptr<Object> o1 = std::unique_ptr<Object>(new Foo());
std::unique_ptr<Object> o2 = std::unique_ptr<Object>(new Bar());
std::unique_ptr<Object> o3 = std::unique_ptr<Object>(new Foo());
std::unique_ptr<Object> o4 = std::unique_ptr<Object>(new Bar());
std::vector<Object*> objects = Object::get_all();
for (auto o : objects)
{
o->print();
}
std::cout << "-----" << std::endl;
std::vector<Foo*> foos = Object::get_bytype<Foo>();
for (auto o : foos)
{
o->print();
}
std::cout << "-----" << std::endl;
std::vector<Bar*> bars = Object::get_bytype<Bar>();
for (auto o : bars)
{
o->print();
}
}
The above example produces the following output
I'm a class Foo object # 003FED00
I'm a class Bar object # 003FED30
I'm a class Foo object # 003FED60
I'm a class Bar object # 003FED90
I'm a class Foo object # 003FED00
I'm a class Foo object # 003FED60
I'm a class Bar object # 003FED30
I'm a class Bar object # 003FED90

C++: Is it possible to have a template class which represents a conditional reference to a resource?

So sometimes I want an object to have a reference to a shared resource (let's say something of type A), or alternatively to have its own copy of an A.
Furthermore the object may find itself inserted and manipulated inside of containers (vector, list, set).
So far what I know is that I will want to use an implementation of unique_ptr if I have a polymorphic type that is to be in a container. So for a class HasAnA which owns an A to be able to be placed inside a container while still allowing its A's to also be B's (B in this case being a derived class of A), it must be like this:
class A {
virtual void a() { std::cout << "A" << endl; }
payloadA payload;
};
class B: public A {
void a() { std::cout << "A(B)" << endl; }
void b() { std::cout << "B" << endl; }
payloadB payload;
};
class HasAnA {
std::unique_ptr<A> my_A; // this allows me to build a std::vector<HasAnA>
OtherStuff my_other_stuff;
};
So this is great, what I'm looking for is how to implement a class I'll call RefersAnA. I'd like for a RefersAnA to either have ownership of its own A, OR refer to an A owned by something else.
Let's see.
class RefersAnA {
std::unique_ptr<A> my_A; // represents my own A: when I die, this A is dealloc'd
A* not_my_A; // someone else's A.
OtherStuff my_other_stuff;
RefersAnA () {
// in here is code that would skip initializing my_A if a valid A* was provided.
}
};
To me this isn't really as friendly as I would like. Could I make some sort of template class which abstracts the notion of "either being a unique ptr to the resource or a raw ptr to the resource"? It needs one bit to say which of the two it is, and one pointer.
Here's an idea:
struct RefersOrOwns
{
std::unique_ptr<T> own;
T & ref;
RefersOrOwns() : own(new T), ref(*own) { }
RefersOrOwns(T & t) : ref(t) { }
};
(Instead of own(new T) I would of course prefer own(make_unique<T>()), but that's a separate issue.)

Making a copy of an object of abstract base class

If I have a pointer to an object that derives from an abstract base class (so I cannot create an new object of that class), and I wish to make a deep copy of said object, is there a more concise way of accomplishing that than to have the abstract base class create a new pure virtual copy function that every inheriting class has to implement?
No, but the copy method does not have to be painful:
class Derived : public Base
{
public:
Base *copy() const
{
return new Derived(*this);
}
};
(assuming you already have a copy constructor, which, if you need a deep copy, you'll have).
The suggested 'copy', more usually called 'clone' is the normal approach. An alternative would be a factory and dispatch using rtti to find the right handler to then call the copy constructor on the derived type.
struct Abc
{
virtual void who() const = 0;
};
struct A : Abc
{
virtual void who() const { std::cout << "A" << std::endl;}
};
template<class T>
Abc* clone(Abc* abc)
{
T* t = dynamic_cast<T*>(abc);
if (t == 0)
return 0;
return new T(*t);
}
struct B : Abc
{
virtual void who() const { std::cout << "B" << std::endl;}
};
typedef Abc* (*Cloner)(Abc*);
std::map<std::string, Cloner> clones;
void defineClones()
{
clones[ typeid (A).name() ] = &clone<A>;
clones[ typeid (B).name() ] = &clone<B>;
}
Abc* clone(Abc* abc)
{
Abc* ret = 0;
const char* typeName = typeid(*abc).name();
if (clones.find(typeName) != clones.end())
{
Cloner cloner = clones[typeName];
ret = (*cloner)(abc);
}
return ret;
}
void test ()
{
defineClones();
Abc* a = new A;
Abc* anotherA = clone(a);
anotherA->who();
Abc* b = new B;
Abc* anotherB = clone(b);
anotherB->who();
}
Whilst the above works, the sheer fact it uses rtti would be enough to persuade most to go the normal approach. However, it there was a reason preventing changes to the base class, it might be useful.
It this efficient? The marginal cost of adding a new type is truly a one-liner. The catch is that it will be easy to forget to add that line with each new class. Or you can see it as an upside that all the clone code lives in a single file and we don't have to change the supported hierarchy to handle it.
A while back someone in comp.lang.c++ asked how to automatically create a clone() function. Someone else provided an idea upon which I expanded. None of it is tested code and I've never actually tried it...but I think it works: http://groups.google.com/group/comp.lang.c++/browse_thread/thread/c01181365d327b2f/9c99f46a8a64242e?hl=en&ie=UTF-8&oe=utf-8&q=comp.lang.c%2B%2B+noah+roberts+clone&pli=1