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.

9
  • You cannot do this. You need to learn about inheritance and polymorphism. Commented Dec 27, 2018 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. Commented Dec 27, 2018 at 21:15
  • @Peter M Do you mean a logical or bitwise or? Commented Dec 27, 2018 at 21:35
  • I meant a Logical Or Commented Dec 27, 2018 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. Commented Dec 28, 2018 at 0:06

1 Answer 1

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.

9
  • 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? Commented Dec 27, 2018 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. Commented Dec 27, 2018 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! Commented Dec 27, 2018 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. Commented Dec 27, 2018 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. Commented Dec 28, 2018 at 0:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.