Instantiation of objects in conditionals c++
let's say I want to instantiate a different type of object depending on certain circumstances, so i would instantiate them inside the body of an if statement. The problem is if you want to use that object later, you need to declare it before instantiation. How does one declare a generic object. Is there something similar to the object class in Java? 开发者_StackOverflow中文版
I've done some google searching like "generic object c++" and "object class c++" and there doesn't appear to be something like that.
This problem can be solved with interfaces. Now, C++ doesn't know interfaces, but you can easily do something similar with abstract base classes:
class Base { ... }
class A : public Base { ... } // A is a Base
class B : public Base { ... } // B is a Base
...
Base *X; // that's what you will end up using
if (some_condition)
X = new A(); // valid, since A is a Base
else
X = new B(); // equally valid, since B is a Base
This will require you to put common functionality into the base class so that you can actually perform operations on X
.
(If you derived all your classes from something like Base
, you'd end up with a super-class like it's available in e.g. C# or Java. However, in my opinion, generic programming, ie. templates in C++, have much reduced the need for a super-class like that. I'd wager that you'll be able to find better code designs in most cases.)
Unlike Java, C++ has no "mother" object which all classes inherit from. In order to accomplish what you're talking about, you'd need to use a base pointer of your own class hierarchy.
Animal* a;
if (...) a = new Cat();
else if (...) a = new Dog();
Also, because there's no garbage collection either, it's better to use smart pointers when you do this sort of thing. Otherwise, be sure you remember to delete a
. You also need to make sure that Animal
has a virtual destructor.
There's no "ancestor of all classes" in C++. But there are some options for doing similar things.
As stakx suggests, make a base class if possible. This is the best from an object-oriented design perspective. Are there common operations that you want to apply to all the objects? If so, try to write an interface, and make the interface a base class. Alternatively, you can use templates to get compile-time polymorphism instead of runtime polymorphism.
If this is too difficult, then look at a wrapper class like boost::any
. That can hold any (copyable) type. It's an opaque wrapper, and you have to know the exact type of data that was put into it, to get it back out. For example, if you put in a Derived *
, you need to use boost::any_cast<Derived *>(wrapped)
to get the data back - boost::any_cast<Base *>(wrapped)
won't work.
std::shared_ptr<Base> X( some_condition ? new A() : new B() );
Heap solutions are expensive and error prone. For not too heavy objects without heap allocations on construction the following approach is preferrable:
Derived1 d1;
Derived2 d2;
Base * b = 0;
if (useD1) {
b = &d1;
} else {
b = &d2;
}
Here we peallocate both types we might need on the stack. No heap allocation, no delete operators, no smartpointers. The only problem - doesn't scale to complex classes to be preallocated.
There is no common base class in C++, so you should define such common ancestor yourself if you the author of these classes or you can use void* although I wouldn't recommend the latter.
If you can't modify the classes then you can introduce wrappers that implement the interface that you need as illustrated below:
class A {};
class B {};
class MyBase
{
// Define the interface that you need.
};
class MyA : public MyBase
{
private:
A a;
public:
// Implement MyBase in terms of A.
};
class MyB : public MyBase
{
private:
B b;
public:
// Implement MyBase in terms of B.
};
int main ()
{
MyBase* base = 0;
if (useA)
base = new MyA();
else
base = new MyB();
}
精彩评论