I have a C++ program A.cpp and I'm including two header files X.h and Y.h. This program(A.cpp) has a class 'foo' and the prototypes of all members of that class. The implementation of this class is done in X.h and Y.h. Both of them contain different definitions of the member functions. But the inclusion of one these files is done conditionally using #ifdef in the program. So if a certain condition is satisified, X.h is #include-ed, else Y.h is #include-ed. Both of them are never included together. Here's the problem: I need to change this compile-time toggle to run-time toggle. I know a header file cannot be included during run-time, so is there any way in which I can "choose" which implementation I want, without using namespaces? Overloading is ruled out, because the functions' prototypes are the same.
Thanks a lot.
(Sorry if this is stupid. I a newbie in C++)
If you want two different behaviours at runtime, then it sounds like you're describing polymorphism. Consider writing two different classes that inherit from a common base-class with virtual functions. Then at runtime you can do things like this:
Animal &a = (x == 3) ? Dog() : Cat();
a.talk();
Perhaps you want to consider a static factory method pattern? You can have a single method which returns the instance of your choice to the caller. You would need to subclass as OliCharlesworth suggests, then this would make it transparent to the calling code.
In pseudocode.
class baseclass{
...
static baseclass *GimmeImpl(){
if(aImpl){
return A();
}else{
return B();
}
}
};
class A:public baseclass {...};
class B:public baseclass {...};
Related
I want to use an abstract base class for the purpose of interfacing and usability. This abstract base class will be used as the parent class for several different derived classes, each of which has need of a certain subset of the pure virtual functions in the abstract base class. An outline of my scheme is as follows.
abstractclass.hpp
AbstractClass{
/* Declaration */
void pureVirt1() = 0;
void pureVirt2() = 0;
void pureVirt3() = 0;
};
derivedclass1.hpp
DerivedClass1{
/* Declaration */
void pureVirt1();
};
derivedclass2.hpp
DerivedClass2{
/* Declaration */
void pureVirt2();
};
derivedclass3.hpp
DerivedClass3{
/* Declaration */
void pureVirt3();
};
Given the current implementation, all of the above classes are abstract classes and no objects can be created from these classes. In the past, I have resolved this issue with preprocesser directives around each virtual function.
abstractclass.hpp
AbstractClass{
#ifdef _1
void purVirt1()=0;
#endif
...
And at the top of each derived class's header file, before the include to abstractclass.hpp I would write something like the following
derivedclass1.hpp
#define _1
#include"abstractclass.hpp"
...
This worked when I was working with small projects and not writing make files. The header for the abstract class was effectively altered based on which derived class was using it, so long as I kept my directives in the correct place. Now that I am using makefiles, this does not work. abstractcalss.cpp is compiled without any of the virtual functions in the header file because it is compiled separately from the derivedclass. I am looking for a good workaround for this.
I want this functionality because I have many similar derived classes from this abstract base class that are used by a variety of other tools I have written. I want to keep these other tools as simple as possible and just use pointers to the abstract class instead of writing template classes for everything.
--Further information
I have a situation where AbstractClass is in a has-a relationship with SubAbstractClass and is implemented by use of having a pointer to SubAbstractClass in AbstractClass. Furthermore, for each of the derived classes there is a similar has-a relationship with SubDerivedClass1, SubDerivedClass2, … I don’t want to write containers for every new class that I create, especially because I can combine my derived classes to create novel classes that are important and functional and any such combination of new classes would require creating the appropriate set of subclasses. To this end, it is useful to have an ABC to allow the pointers to be declared once and work for any derived class.
[...] several different derived classes, each of which has need of a
certain subset of the pure virtual functions in the abstract base
class.
Obviously, this won't work. Moreover, your attempts to make things simpler are, in my opinion, having the opposite effect. You are making things much more complex by introducing preprocessor black magic to comment-in and comment-out specific parts of the interfaces.
You're swimming upstream without a paddle here. Instead of having one interface class to which you add and remove methods piecemeal, just develop several different interface classes that do a better job of modularizing the functionality:
AbstractClass1{
/* Declaration */
void pureVirt1() = 0;
};
AbstractClass2{
/* Declaration */
void pureVirt2() = 0;
};
AbstractClass3{
/* Declaration */
void pureVirt3() = 0;
};
Trying to make one universal, God class that you blow pieces off of to suit specific modules's needs is going to eventually bite you, and hard. Consider what might happen when you need two instantiations of the interface in the same translation unit, but each of those instantiations have different pieced #defineed in. Sounds like a nightmare to me.
Start with a common base class.
class AbstractBaseClass {
// common stuff goes here
};
Then, create abstract interfaces for the sub-versions:
class AbstractSubClass1:public AbstractBaseClass {
public:
void pureVirt1() = 0;
};
class AbstractSubClass2:public AbstractBaseClass {
public:
void pureVirt2() = 0;
};
class AbstractSubClass3:public AbstractBaseClass {
public:
void pureVirt3() = 0;
};
which contain the abstract pureVirt methods.
Finally, derive your implementation classes form the sub classes:
class Derived1 : public AbstractSubClass1 {
virtual void pureVirt1() override; // override if your compiler supports it
};
class Derived2 : public AbstractSubClass2 {
virtual void pureVirt2() override; // override if your compiler supports it
};
class Derived3 : public AbstractSubClass3 {
virtual void pureVirt3() override; // override if your compiler supports it
};
now, objects that know you are a particular sub class can access the pureVirtX member. Those that don't only have access to the common AbstractBaseClass interface (whatever that is - you mention that some code doesn't need to know about these particular virtual methods).
I am new at building distributable libraries written in C++ and I am getting a bit lost.
I have created a .cpp file with wrappers for all functions I want the library to offer users, and I have written 2 .h files, one public and one private. Below is a dummy example of my header files:
public.h:
class myclass
{
public:
public_function();
private:
}
private.h:
class myclass
{
public:
public_function();
private:
anotherClass instanceofClass;
}
Note that the implementation of public_function() uses the "instanceofClass" in the code.
I have been able to compile with no problem the code using the private class and to compile and link the library with external programs using the public header and the compiled library. When executing that code, though, I am getting segmentation faults that I suspect have to do with lack of proper initialization of "instanceofClass".
Am I doing the right thing? Am I forced to instantiate "instanceofClass" inside the implementation of public_function() for it to be initialized properly, or is there anything else I should do instead?
Thanks a lot.
You can't declare the same class 'myclass' in two different ways. There has to be a single class definition. If you want to hide the implementation's API you want to use the 'Pimpl' idiom. So your public class has a single pointer to a private class. For example:
public.h
class myclass_private;
class myclass {
private:
myclass_private* pimpl;
public:
myclass();
void public_function();
};
public.cpp
myclass::myclass() {
pimpl = new myclass_private;
}
void myclass::public_function() {
pimpl->private_function();
}
private.h
class myclass_private {
public:
void private_function();
};
The myclass defined in public.h has no members, and is therefore sized 1 byte. The myclass defined in private.h encapsulates anotherClass, and is therefore whatever size anotherClass is. This inconsistency is the root of your problem.
What you ought to do is have only one header, and use a pointer (which doesn't require a class definition) to enable hiding the implementation of anotherClass. I'll repeat Joachim's link to the pimpl idiom for elaboration.
The definition of a class shall not changr between different translation units. This is one of the aspects of the One Definition Rule. What you might want to donis to define the publicly visible class to have a pointer to a private implementation: the Pimpl Idiom:
class Public {
public:
...
private:
struct Impl;
Impl* impl_;
};
The struct Impl would only be defined in the implementation file.
Your class lacks a proper constructor, which means that the compiler will provide a default one based on the content of the class definition. If that definition isn't consistent accross all the code, it won't get initialized the same way everywhere, and some data may be missing.
If you want to hide the implementation details of instanceofClass, just do a forward declaration in the header (the private header you're providing is correct, you can use it as your public one), and provide an implementation somewhere in your code.
I have already seen a post about the error but This is some what different. So please donot close this. I have an Interface class and I have a class that inherits the interface class and overides the methods in Interface class. The code looks likes this
//interface file
//Interface.h
class A
{
virtual method1();
};
//b.h
#include "Interface.h"
class B : public A
{
//declaration
}
//b.cxx
#include b.h
B::method1()
{
//definition
}
I am exporting all these classes in a dll. And I am using methods and classes in the dll from an exe. This exe agains contains somes classes. These classes again inherit the same interface file and also uses method1(). So to use method1() I am including b.h in my file. If order of my include statements are Interface.h and b.h, then I am getting Compiler error for exe. Telling "base class not defined". But if I reorder the Include statement there is no compilation error. Can any one suggest me what could be basic reason for this problem.
There are actually two errors in your example code: First you do not declare the method without a return type, which is an error. The second is that you, at least in the snippet above, do not declare method1 in the class definition of B:
class B : public A
{
virtual void method1();
};
You absolutely need to declare virtual method "method1()" in both A and B's class definition.
If you interface is IA and is declared in IA.h , make sure that every class Foo that inherits from IA be it in the exe or dll includes IA.h before the class definition in Foo.h
What I suspect is happening that this is not the case and based on the header include order you might be getting the definition of IA in certain files and not in the others
Last year I saw some source code (C++) where its author declares static function in base class, but leaves its definition to derived class. I remember there was constraint that only one derived class was permitted to define aforementioned static function.
I know that it is impossible to override static methods, but this trick is exactly what I need. I just can't make it work in my code :) Does anyone know about this feature?
Lets look why this would be useful. Suppose we have some base class (Shape), and its derived classes (Circle, Triangle...). Suppose Shape is part of my core architecture, and derived classes are treated as plugins. I don't want to change my core architecture in future. So we have:
class Shape
{
//other stuff here
static Shape* Factory();
}
class Circle:Shape
{
//other stuff here
static Shape* Factory();
}
Shape is sort of abstract class, and it will not implement Factory method. Method is implemented by one (and only one) of the derived classes. In implementation derived class will return new instance of itself, so it is just a factory method. This trick allowed its author to use this static method in client class in following way:
class Client
{
public Shape* shape;
public Client();
//other stuff here
}
In implementation of constructor he had something like:
Client::Client()
:shape(Shape::Factory())
{
}
This way he was able to instantiate "right" shape derivation without changing core classes in engine. When he wanted some other shape to be used in core classes he just had to define static Factory method in that derived class (and to remove the existing one in other derived class).
This way we have some sort of "static polymorphism". I can't find anything about this technique on the web. Does it even have a name? I am especially interested if something like this could be achieved in C# language? :)
Thanks in advance, and sorry for my bad English.
What it sounds like you are trying to do is a bit messy in my opinion. It feels like a combination of a Factory class, a Singleton and then trying to squish them all back into your result class hierarchy.
The simplest (not necessarily the best) solution I can think of is forget about having either Circle::Factory() or Shape::Factory() and just have a free function called get_default_shape().
class Shape
{
};
class Circle: public Shape
{
};
Shape * get_default_shape()
{
return new Circle;
}
Client::Client()
:shape(get_default_shape())
{
}
The nice bit about this is that its only the implementation of get_default_shape that needs to include Circle.h, all the definition needs is a forward declaration of the Shape class.
Hmm. I have not seen exactly what you describe. It could be that the piece of code you refer to defined the base class static function in the cpp file containing your derived class.
// definition of Circle class
.....
Shape* Shape::Factory()
{
return new Circle();
}
This is not useful in this example but it could be a useful trick if you want to hide the implementation of a class and only publish an abstract base class (to reduce compile time dependencies). It won't work if the base and derived classes are not in the same dll/exe.
Similar things can be achieved in C# by using an IOC framework, with generics, or by registring a factory delegate in your base class. I tend to prefer generics and delegates.
Edit: Thanks folks, now I see my mistake.
If I'm not wrong, because of its nature in factory method there is cyclic dependency:
Base class needs to know subclasses because it creates them, and subclasses need to know base class. Having cyclic dependency is bad programming practice, is not it?
Practically I implemented a factory, I have problem above, even I added
#ifndef MYCLASS_H
#define MYCLASS_H
#endif
I'm still getting
Compiler Error C2504 'class' : base class undefined
And this error disappers when I remove subclass include from base class header.
Solution 1: don't #include the derived class headers in the base class header, only in the base class cpp. The declaration of the factory method should not use the type of concrete classes returned, only the base type.
Solution 2: use a separate factory class (or a factory method within a separate class) to create your objects. Then the cyclic dependency is totally eliminated. This is the preferred way.
The factory shouldn't be a base class of the products.
Base classes never need to know about derived classes.
You need to revisit your pattern description, because I think you might be mixing a couple of different patterns together: if you're using it to create derived classes, then the factory shouldn't be part of the base class. If you're just using it to create various instances of a single class, then it could be a static member of that class.
In the error message you're getting above, the derived classes always need to know the full implementation of the base class. As a design matter, base classes should never know anything about derived classes.
struct Base {
Base * Create(int param);
};
struct Derived0 : public Base {
};
struct Derived1 : public Base {
};
Base * Base::Create(int param) {
switch (param) {
case 0: return new Derived0();
case 1: return new Derived1();
}
You should not try to implement the factory function within the Base class definition. Simply declare it there, and define it after the derived classes definitions.