0

I'm working in C++14 and trying to figure out a way to put two classes (with the same name) inside the same header file. In this scenario one class would always be ignored as a result of something happening in main.cpp during runtime. Here's an example of this header file:

// First class:
class foo
{
public:
    foo();
private:
    int var;
};

foo::foo()
{
    var = 1;
}

// Second class:
class foo
{
public:
    foo();
private:
    int var;
};

foo::foo()
{
    var = 2;
}

So let's say during runtime the user entered "1". Then the first definition of class foo would be used, and the compiler would ignore the second class. But then if the user enters "2", the first class is ignored and the second class is used.

I know it's ugly, but in my specific case it saves a ton of work.

  • You cannot do this. You need to learn about inheritance and polymorphism. – GrandmasterB Dec 27 '18 at 21:12
  • 2
    Either you need a time machine in order for the runtime to affect the compilation process or you are not being clear what you exactly want to do. – Peter M Dec 27 '18 at 21:15
  • @Peter M Do you mean a logical or bitwise or? – Inertial Ignorance Dec 27 '18 at 21:35
  • I meant a Logical Or – Peter M Dec 27 '18 at 23:03
  • 1
    I guess what you are really after is "foo" as an abstract base class of two other classes "foo1" and "foo2", and a factory method which creates either objects of type "foo1" or "foo2", which are then used as "foo" objects throughout the rest of the program. This approach has a name, it is called Strategy pattern. – Doc Brown Dec 28 '18 at 0:06
1

Technically, it's possible

You can give two different classes the same name, by putting each class in separate namespaces:

namespace space_1 {
    class foo { ... }; 
}  

namespace space_2 {
    class foo { ... }; 
}

This defines two different and unrelated classes: space_1::foo and space_2::foo.

You may then define at compile time which namespace to use in the using context (in main(), or in a configuration header):

int main() {
    using namespace space_1; 
    foo a; 
}

If you want to choose either the one or the other at run time, you'll have to either use explicit scope resolution, or use the class and the defined object in a limited scope using a namespace:

if (a) {
    using namespace space_1; 
    foo f; 
    // do smething with f HERE 
}
else {
    using namespace space_2; 
    foo f; 
    // do something else with f HERE
}

But does it make sense ?

Using different namespaces for classes with the same name is typically used for managing compile-time library dependencies, for example:

  • avoiding name conflicts between different components.
  • new version of a library with a different interface.
  • choice of alternative libraries (e.g. boost::xxx vs. std::xxx).

It is a very bad idea to use this construct for a different purpose, such as choosing the class implementations at runtime.

Is there a better design ?

If you have a class with a well defined API, but need to cope with different variants/implementations at run time, you may consider polymorphism:

  • Make foo an abstract base class, and create a derived class for every needed variant.
  • Use a factory to instantiate the objects with the right derived class.

Alternatively, you may redesign your foo class, so that it requires a parameter in the constructor (i.e. the initial value of var in your case) or inject a strategy in the constructor.

  • I was under the impression that #define is only typed once at the start of a program. There's a way to use #define on two namespaces throughout a program to switch back and forth between their respective classes? – Inertial Ignorance Dec 27 '18 at 21:38
  • I'm actually already doing what you coded (using different namespaces for my classes). It's worked well so far since I only ever use two classes at the same time. Now though I want to use 10+ of these classes, which would require 10 different namespaces. That would mean I have 10 different kinds of pointers/objects, requiring 10 different (essentially identical) functions for operating on each kind of pointer. I was hoping to get around this somehow. – Inertial Ignorance Dec 27 '18 at 21:43
  • 1
    Yeah an abstract class is probably the best way to go, not sure why I didn't give it much thought. It would allow me to write functions acting on the same type for all 10 different objects. Thx! – Inertial Ignorance Dec 27 '18 at 21:53
  • 1
    The question was "one class would always be ignored as a result of something happening in main.cpp during runtime" - but what you are showing above is a compile time decision, not a runtime decision. So either OP (in accepting your answer) did not understand what they were asking for, or they did not understand what your answer is about, or I did not understand something here. – Doc Brown Dec 27 '18 at 23:53
  • 1
    @Christophe: I think it would be better if you edit your answer in a way other readers are not forced to scan through all the comments to understand why you did not answer the literal question, as it is written. – Doc Brown Dec 28 '18 at 0:59

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.