Declare one object to be of multiple classes, depending on a condition - c++

This question is based on Create objects in conditional c++ statements.
However, in my case I need to declare one object from a choice of multiple classes which will then be passed as argument to a function. Hence, the object has to be declared with a pre-defined name (obj in this case).
Class1 obj;
Class2 obj;
if (...) {
obj = Class1(); }
if (...) {
obj = Class1(a, b); }
else
obj = Class2();
// Do something on declared object
DoSomething(obj.variable_);
Currently the above will not work because of conflicting declaration of obj. How should I go about doing this?

You might not need std::variant, if your object doesn't have to be "polymorphic" at run-time. Refactor your code to:
if (...) {
DoSomething(Class1());
if (...) {
DoSomething(Class1(a, b));
else
DoSomething(Class2());
And make DoSomething a template or overload set:
void DoSomething(const Class1&) { }
void DoSomething(const Class2&) { }

You can use std::variant.
std::variant<Class1, Class2> var;
if (...) {
var = Class1(); }
if (...) {
var = Class1(a, b); }
else
var = Class2();
std::visit([](auto&& obj) { DoSomething(obj.variable_); }, var);
The variant can hold one of the alternatives at a time, which is what you need. And std::visit will let you apply code generically to either alternative, so long as the generic lambda can be applied to it.

Solution using simple polymorphism,
ClassBase () {
}
Class1 : ClassBase (){
}
Class2 : ClassBase (){
}
Then you can use like,
ClassBase obj;
if (...) {
obj = Class1(); }
if (...) {
obj = Class1(a, b); }
else
obj = Class2();
// Do something on declared object
DoSomething(obj.variable_);

The OP said: "Class1 and Class2 can inherit from a common base class. I can provide overload of DoSomething"
Inheritance is OK. But only if it is in a form of "subtyping". Let's assume everyone is aware of that. Canonical example.
In this case OP's question and code is actually internals of a factory method. One solution might be:
Interface::ptr make ( Interface::subtype which)
{
if ( which == Interface::subtype::one )
return std::make_unique<Class1>();
return std::make_unique<Class2>();
}
And the usage is simple:
Interface::ptr one = make( Interface::subtype::one ) ;
Interface::ptr two = make( Interface::subtype::two ) ;
one->do_something() ;
two->do_something() ;
Jut one variant of the common concept. Working code is here.
Option with no polymorphism required
Is allways a good option. We do not need inheritance. We just need intances that do understand the message do_something().
// no inheritance required
template<typename T>
void do_something( T the_t_ ) { the_t_.do_something(); }
Ditto
if ( ... ) {
do_something(Class1{}) ;
}
else if ( ... ) {
do_something(Class1(a,b)) ;
} else {
do_something(Class2());
}
In that case Class1 and Class2 do not need a common base type.
ps: Vittorio's solution is very good. It can be also applied when Class1 and Class2 are completely unrelated.
An interesting variant of that variant could be:
if (...) {
Class1();
if (...) {
Class1(a, b);
else
Class2();
No function overloads DoSomething() but type instances that "do something". Might be the most feasible design but only for some app's.

Related

Check if class is instantiated in method

I have a class that has a few static functions that can be called even if there is no instance of that class. There is also a method init() that I use to set some variables. This method is not static thus it needs an instance. Now if this was done I want the static methods to behave differently. Sort of like:
static foo(){
if(noInstance()){
doA();
}else(){
doB();
}
}
Is this even possible? Or a bad idea and should just make the user call different methods if there is an instance?
Thanks
EDIT
It sounds weird but this is my use case:
class A{
public:
static inline bool hasInstance = false;
int data;
static int getData(){
if(hasInstance){
return data; // Can't do this from a static function
}else{
return 0;
}
}
};
I know that I cant access the data from a static function beacuse there is no this pointer. I'm coding a library and I want the user to be able to use the static method if he dosen't want an instance but if there is an instance it should make use of the data of its instance.
If had an idea but I don't know wether that's good style:
static int getData(A *ref){
if(ref != nullptr){
return data;
}else{
return 0;
}
}
I'd glad to hear from someone with more experience wether I should do that.
I think you can use a static variable, let it be named count. You initialize count with 0, and every time you create an instance of that class, you increment count. If count is 0, that means you did not created any instance, therefore you can't use some methods.
I'm coding a library and I want the user to be able to use the static method if he dosen't want an instance but if there is an instance it should make use of the data of its instance.
In general, free functions are recommended rather than member functions (gotw). It is actually rare to have good reasons to make a static function a member function. It would need to be a member if it would need access to privates of the class, but that doesnt seem to be the case here and then it still could be a friend function.
Let's look at your approach:
static int getData(A *ref){
if(ref != nullptr){
return data;
}else{
return 0;
}
}
You probably meant to write ref->data;, also I guess you are not merely returning the value of the member. That would be of little use, because If I have an instance I can get my hands on x.data without needing to call getData. And I suppose 0 is just a placeholder for someother value that you have there in the real code.
I am going a bit subjective now...
If I was a user of your library, I would want to know if getData returns data from one of the objects I did create or something else. Having one and the same function that does both would confuse me. I don't like pointers and I am scared of nullpointers, so if you force me to write
getData(nullptr);
this would not make me happy. I would like to have two different functions:
int getData() { return 0; }
int getData(const A& x) { return x.data; }
If I have no instance, I can call the first, if I have one I can call the second.
Not sure what is your final goal, but I would recommend reconsidering your design, because this static/hasInstance behavior smells.
Anyway, here is what you need:
using namespace std;
#include <iostream>
class MyClass
{
private:
static bool hasInstance;
public:
MyClass()
{
hasInstance = true;
}
static void foo()
{
if (hasInstance) {
std::cout << "I have an instance\n";
}
else {
std::cout << "No instance\n";
}
}
};
bool MyClass::hasInstance = false;
int main () {
MyClass::foo();
MyClass a;
a.foo();
MyClass::foo();
return 0;
}
EDIT:
Don't use it in real code. If you just curious, you can do almost everything in C++, so you could pass the object sometimes, it's dirty and ugly, but just for the demo:
using namespace std;
#include <iostream>
class MyClass
{
private:
int someVariable;
public:
MyClass()
{
someVariable = 42;
}
static void foo(MyClass *obj = nullptr)
{
if (obj) {
std::cout << obj->someVariable << std::endl;
}
else {
std::cout << "No instance\n";
}
}
};
int main () {
MyClass::foo();
MyClass a;
a.foo(&a);
MyClass::foo(&a);
return 0;
}

Inheritance and pointers

I have code like this:
class Human
{
protected:
int age;
std::string sex;
public:
virtual void speak() = 0;
};
class Child:public Human
{
public:
void speak(){std::cout << "I am Child\n";}
};
class Man:public Human
{
public:
void speak(){std::cout << "I am Man\n";}
};
class Woman:public Human
{
public:
void speak(){std::cout << "I am Woman\n";}
};
(don't know, std::shared_ptr<Human> maybe?) operator*(std::shared_ptr<Child> &b, int x)
{
b->setAge(b->getAge()+x);
if(b->getAge()>18 && b->getSex()=="Man")
{
return (i want b to become std::shared_ptr<Man>)
}
if(b->getAge()>18 && b->getSex()=="Woman")
{
return (here I want b to become std::shared_ptr<Woman>);
}
return;
}
int main(){
auto x = std::make_shared<Child>;
x*19;
}
I know it seems odd, but it's the simplest case i can think of, without having to write down all code i'm struggling with rn. Could someone explain, what type should overload be and how to change shared_ptr type, knowing they derive from same parent?
Objects cannot change type. A Child object will always be a Child object. What you can do is create a new object with the properties you want and return that:
std::shared_ptr<Human> operator*(std::shared_ptr<Human> b, int x)
{
b->setAge(b->getAge()+x);
if(b->getAge()>18 && b->getSex()=="Man") {
return std::make_shared<Man>(b->getAge());
} else if(b->getAge()>18 && b->getSex()=="Woman") {
return std::make_shared<Woman>(b->getAge());
} else {
return b;
}
}
int main(){
std::shared_ptr<Human> x = std::make_shared<Child>;
x = x*19;
}
This doesn't seem like a good design though. A Human's status as a child or adult would be better represented as an attribute of the object or by a function that checks if age is greater than 18.
You cannot make the type T<Derived> inherit from T<Base> because C++ templates do not support covariance. To do so would be unsafe for certain types, such as mutable references to containers. (Imagine taking a reference to std::vector<Cat> as std::vector<Animal>& and pushing back a dog!)
(I would make this answer a comment, but I don't have comment abilities.)
Update:
You can write a non-template wrapper that handles heap data:
class Wrapper
{
public:
Wrapper(Base* b) : raw(b) {}
~Wrapper() { delete raw; }
Base& get() { return *base; }
private:
Base* raw;
}
Of course, in your example, you use std::shared_ptr and not std::unique_ptr. You would have to handle reference counting instead of simply deleting the data in the destructor, but the technique of keeping an internal raw pointer still stands.
Update 2:
The above code could be used as is to provide a level of indirection, such that all classes that inherit from the base class may be held in the same type, without writing your own reference counter:
std::shared_ptr<Wrapper>
This solution may be seen as similar to doing std::shared_ptr<Base*>, except that the latter solution would leak memory.

How to correctly manage 2 containers of different types in a class?

I have the following (kinda pseudo) code, which handles 2 containers of 2 different (but somewhat similiar) types, and I hate having these duplications for addition and deletion (and also 2 searching functions in my real code)
class PureAbstractClass
{
public:
virtual char Func() = 0;
}
class PureOpt1 : PureAbstract
{
public:
virtual int FOption1(A, B, C) = 0; // Notice 'C'
}
class PureOpt2 : PureAbstract
{
public:
virtual int FOption2(A, B, D) = 0; // Notice 'D'
}
class Handler
{
public:
void Add(PureOpt1* arg) { v1.add(arg); }
void Add(PureOpt2* arg) { v2.add(arg); }
// This is implemented using lambda
// Sorry for LINQ syntax, lambdas are too long for pseudo code
void Del1(char c) { arg = v1.find(obj => obj->Func() == c); v1.del(arg); }
void Del2(char c) { arg = v2.find(obj => obj->Func() == c); v2.del(arg); }
void Process(ch, A, B, C, D)
{
o1 = v1.Find(obj => obj->Func() == ch);
if( null == o1 )
{
o2 = v2.Find(obj => obj->Func() == ch);
if( null == o2 )
{
DoSomething();
}
else
{
o2->FOption2(A, B, D);
}
}
else
{
o1->FOption1(A, B, C);
}
}
private:
vector<PureOpt1*> v1;
vector<PureOpt2*> v2;
}
Having Handler be a template class is impossible because of Process().
Is there a more correct way to implement this kind of code?
How to correctly manage 2 containers of different types in a class?
Answer is use only 1 container.
Simplest solution would be to have pure vitual method in base class:
class PureAbstractClass
{
public:
virtual char Func() = 0;
virtual int FOption(A, B, C, D) = 0;
}
then both children override FOption() and ignore parameter they do not need. There could be better solution but you do not provide enough information. Your solution - to keep them in 2 separate containers is probably the worst. As you can see your solution conflicts with inheritance (you remove inheritance and make both children independent classes and nothing would change in your code). Alternatively you can use dynamic_cast, but using it usually shows bad program design:
PureAbstractClass *o = find( ... );
if( !o ) {
DoSomething();
return;
}
if( PureOpt1 *po1 = dynamic_cast<PureOpt1 *>( o ) )
po1->FOption1( A, B, C );
else {
if( PureOpt2 *po2 = dynamic_cast<PureOpt2 *>( o ) )
po2->FOption2( A, B, D );
else
// something wrong object is not PureOpt1 nor PureOpt2
}
Note: it is completely unnecessary for FOption1() and FOption2() to be virtual in this case. And you should not forget to add virtual destructor to the base class.
Alternatively you may use boost::variant and visitor patter, in this case you do not need inheritance as well but you can make your code generic.
If possible have the FOption1/2 be int Func(Data const & data). You then create the data and pass it to it. Data can have the four different pieces of information with C and D being optional. The specific implementation of Func can then process that data as it needs

Get list of functions in a namespace at runtime?

Is it possible to get a list of functions in a certain namespace or all functions in a program at runtime?
I have a function pointer map and I need to add commands on my own to it, but I thought: why not create a namespace and let the program do the work at runtime?
something like(pseudocode):
typedef bool (*command)(void);
namespace Commands
{
bool Start(void)
{
return true;
}
bool End(void)
{
return true;
}
};
std::map<std::string,command> CommandMap;
main()
{
for(each function in namespace Commands)
{
CommandMap[std::string(function_name)] = function;
}
CommandMap["Start"]();
CommandMap["End"]();
return 0;
}
instead of
std::map<std::string,command> CommandMap;
main()
{
CommandMap["Start"] = Commands::Start;
CommandMap["End"] = Commands::End;
//list of thousands of other commands......
CommandMap["Start"]();
CommandMap["End"]();
return 0;
}
Is this possible to achieve in C++ or C++11? Or any alternatives to my goal?
No (it has to be 30 characters).
EDIT: This goes along with my comment about how much control you have. You could redefine all of your functions as functors, and have the constructor register itself with some array. Your base class would look like this:
EDIT2: read the comment about all functions having same arguments and return types, makes it a little cleaner.
class myFunctorBaseClass
{
public:
myFunctorClass () : {//register myself, no duplicates}
virtual int operator () (int);//Whatever types you want
};
class myFunctor: public myFunctorBaseClass //Define as many of these as you need
{
public:
int operator() (int y) { return y; } // Define this as whatever you want
}
This obviously would depend on the objects being constucted, but assuming they all were as an initialization step, this would get you what you want.
NOTE: This may be incomplete/not compile. I just kinda wrote this off the top of my head, but it should be close. The reference you want is "functors" if you have questions about how this works.
Consider something like:
class CommandCollection
{
...
void register_command(Command*, string);
map<string, Command*> m_command_map;
}
class Command
{
...
virtual do_command(...) = 0;
}
class EachCommand : public Command
{
EachCommand() { CommandCollection::instance().register_command(this, my_name); }
...
virtual do_command(...);
}
EachCommand each_command_inst;
The Command base class has a virtual to do a command. Each derived type implements the command (you could try overloading the () operator to make them look more like functions).
Each derived Command registers itself with the CommandCollection, so it can be known in a central location. If you want to associate the commands by string (seems good if a user is typing them in), then that would be the key in the map.
As mentioned elsewhere, names (in C and C++, other languages may/do differ on this point) only really exist as part of the source-code. Once compiled, the names cease to have any meaning in C and C++.
One could, however, consider some sort of structure like this:
class CommandBase
{
virtual bool doCommand() = 0;
virtual std::string name() = 0;
virtual ~CommandBase() {}
};
class StartCommand : public CommandBase
{
bool doCommand() { ...; return true }
std::string name() { return "Start"; }
};
void RegisterCommand(CommandBase *cmd)
{
CommandMap[cmd->name] = cmd;
}
...
StartCommand start;
...
void someFunction()
{
RegisterCommand(&start);
}
I'll probably get a downvote for mentioning macros, because these are evil - don't use this if you are a purist that don't like macros.
#define CMD(x) CommandMap[#x] = Command::x
CMD(start);
CMD(end);
There are certainly other variants, and someone who knows templates may well come up with something that does this using templates.

Fluent interface pattern and std::unique_ptr

I am playing with the fluent interface pattern.
First, I wrote something like that:
class C
{
public:
C() { }
C* inParam1(int arg1){ param1 = arg1; return this; }
C* inParam2(int arg2){ param2 = arg2; return this; }
private:
int param1;
int param2;
}
Then I tried to use the std::unique_ptr, but then I realized that I do not know how to "shift" the pointer (this) along the chain. I tried something like:
return std::move(this);
that of course does not work.
How can I do this? Are there any problems doing something like this?
In order to reply to comments like: "do not use pointers": there isn't (yet) any practical reason because I am doing this with pointers, is just something I wonder if can be done this way.
Why do you have to return pointers at all?
class C
{
public:
C create() { return C(); }
C & inParam1(int arg1){ param1 = arg1; return *this; }
C & inParam2(int arg2){ param2 = arg2; return *this; }
private:
C() { }
int param1;
int param2;
};
I must admit I don't understand the purpose of that create function or why the constructor is private or how you actually create objects of this class at all. In my understanding, the class should actually be like this:
class C
{
public:
C() {}
C & inParam1(int arg1){ param1 = arg1; return *this; }
C & inParam2(int arg2){ param2 = arg2; return *this; }
private:
int param1;
int param2;
};
And used like this:
int main()
{
C().inParam1(10).inParam2(20).whatever();
}
There can be only one std::unique_ptr instance for any given instance (because each would try to delete it and that can be done only once). Therefore, while create can return a std::unique_ptr, the other two methods cannot.
Is there any reason why you don't have the other methods return a reference rather than a pointer? And why don't you just have a public constructor? I don't see the value of the create method in this example.
You missed one important think from the c++ fluent interface example :
//it doesn't make sense to chain after create(), so don't return *this
Therefore, you shouldn't return anything from your create() method.
However if you still want to return something, at least do not (mis-)use unique_ptr, and just return a new object :
C create() { return C(); }