I'm new to programming in c++ and struggle with organizing my project.
I have got a class named StateManager, which has a header file and an cpp file.
The cpp contains all implementations.
If I now want to make an Interface class:
class IStateManager
{
public:
virtual ~IStateManager() {}
virtual void SomeMethod {}
};
I know interfaces don't really exist as they do in c# or Java, but I want multiple classes to inherit from this "interface".
Does this class also need an header and a cpp file? Or can I just put it in a header file?
Technically, c++ doesn't have interfaces. However, one can "create" interfaces by way of multiple inheritance (or single inheritance if your class is a "base" class and doesn't need to inherit from multiple classes). Where your "interface" lives is entirely up to you. But if you plan on using a class as an interface (without any actual implementation because technically an interface doesn't have an implementation until the functions are defined in a subclass), I would put it in it's own header file and declare each function pure virtual:
class IStateManager
{
public:
virtual ~IStateManager() {}
virtual void SomeMethod() = 0;
virtual void AnotherMethod() = 0;
};
class TheState : public IStateManager, public SomeOtherParentClass
{
virtual void SomeMethod(); // Defined in this class
virtual void AnotherMethod(); // Also defined in this class
//..
};
If you are defining some implementation in a .cpp for the IStateManager class, then you really have more of an abstract class and not an interface.
So in conclusion what I'm saying is: Any implementation of an "interface" should be defined in the .cpp file of its implementing class. And if you plan on using the interface in multiple files, I would create a separate .h file for it.
You can put the implementation of class methods in the header file. That doesn't mean you should. It also has nothing to do with the fact that this is an "interface" class, as you call it.
I wouldn't call this an interface class by the way, because your virtual methods aren't pure.
Related
I'm working on a simple C++ program and am having a difficult time understanding a compiler error I was getting. The issue was caused by me attempting to create a derived class from a base class. I've posted my code below with the same structure but have changed the names.
BaseClass.h
#ifndef BASECLASS_H
#define BASECLASS_H
class BaseClass {
public:
BaseClass(void);
virtual int method1(void) = 0;
virtual int method2(void) = 0;
virtual float method3(void) = 0;
};
#endif // BASECLASS_H
DerivedClass.h
#ifndef DERIVEDCLASS_H
#define DERIVEDCLASS_H
#include "DerivedClass.h"
class DerivedClass: public BaseClass
{
public:
DerivedClass(void);
};
#endif // DERIVEDCLASS_H
DerivedClass.cpp
#include "DerivedClass.h"
DerivedClass::DerivedClass(void)
{
}
int DerivedClass::method1(void)
{
// TODO
}
int DerivedClass::method2(void)
{
// TODO
}
float DerivedClass::method3(void)
{
// TODO
}
When attempting to compile this, I get the following error for all the virtual methods:
no 'int DerivedClass::methodX()' member function declared in class 'DerivedClass'
As soon as I declare these methods in the 'DerivedClass.h', the errors go away since the compiler is now aware of the methods.
However, I'm confused. Why was it necessary to re-declare the pure virtual functions in DerivedClass.h? When I #include DerivedClass.h, that will automatically include BaseClass.h, thus I assume my DerivedClass.cpp should be fully aware of the methods. Am I doing something incorrect?
It doesn't work this way. You need to declare the methods you're going to define, whether they're overriding a virtual method or not.
This isn't just an unreasonable requirement of the language. Without this you would be unable to define partially virtual class, i.e., you could have BaseSubtype that has common implementation of method1() but requires classes derived from it to implement method2() and method3()
When you declare a method in a derived class, you say to the compiler:
I want to override this method in this class
So if you don't declare a method in the derived class, you say:
I don't want to override this method; derived class's implementation is the same as the one in the base class
In your case, the base class declares them as pure virtual, so in this case it can be paraphrased:
I don't want to implement this method in this class
If you try to define a method but not declare it, you contradict yourself. The compiler detects that (to protect you from your own negligence).
A very non-intuitive reason why overridden virtual methods must be derived in the base class stems from the fact that C++ allows different parts of the class to be placed into different files, into different translation units.
With some other languages (I'm looking in Java's direction), a single class must be placed in a single file. This is not true with C++. It is perfectly legal for a class to have some of its methods declared in one translation unit, and other methods declared in another translation unit, which could be in a file in some different directory altogether.
Each such file gets compiled separately and individually. When compiling one translation, the C++ compiler has no knowledge of any other translation unit, any other file, that might contain other pieces of the same class.
Now let's say that you are allowed to omit an overriden virtual method from the class declaration. This creates an immediate problem: when compiling the class's constructor, it is necessary for the compiler to know whether the class overrides any virtual methods from any of the superclasses, in order to correctly assemble the virtual table dispatch for the class being constructed. Without an explicit declaration, the compiler has no way of knowing whether or not some other translation unit might define an overridden virtual method.
And that's why overridden virtual methods must be explicitly included in the class's declaration. In conclusion: because C++ formally specifies phase 9, the linkage phase, with the actual compilation carried on in earlier phases, overridden methods must be explicitly declared.
you should override all the base class pure virtual functions to be able to instantiate derived class.
you cannot define a base class member function from derived class.
in your example you are trying to define method1 and method2 and method3 which are not members of DerivedClass!! you have to declare them yourself in your derived class. compiler doesn't do it for you.
so your Derivedclass.h will look like:
#ifndef DERIVEDCLASS_H
#define DERIVEDCLASS_H
#include "BaseClass.h"
class DerivedClass: public BaseClass
{
public:
DerivedClass(void);
virtual int method1(void); // not pure function
virtual int method2(void);
virtual float method3(void);
};
#endif // DERIVEDCLASS_H
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 a file GetL.hxx
#ifndef GetL_included
#define GetL_included
#include <iostream>
using namespace std;
class GetL
{
public:
virtual int getWidth();
};
#endif //GetL_include
Here the class GetL contains only one virtual function and thus is a abstract class. How can i create .cxx file for this .hxx file?
This is not an abstract class. An abstract class contains a pure virtual function. For example , if you wanted to make your class abstract you could put virtual int getWidth() = 0; which would force the getWidth() function to be defined in a derived class.
It's probably also worth mentioning that it's not a good idea to put using statements in a header file. It pollutes the current namespace unnecessarily and can lead to naming conflicts.
If your class is supposed to be abstract you should declare getWidth() to be abstract.
Like this virtual int getWidth() = 0;. That makes the function pure virtual, which is a requirement for the class being abstract.
Then there is no need to create a .cxx file, since there is no implementation to go with your totally abstract class.
Only if you have more methods, of which not all are pure virtuals would you be required to create an implementation file. As long as the class consists of only pure virtual functions you do not need to create an implementation.
Edit: To provide an implementation, create a new file called GetL.cxx
#include "GetL.hxx"
int GetL::getWidth() {
// Insert implementation here
}
Depending on your IDE and project settings you may need to #include "stdafx.h" at the top of this implementation file. Note that if you provide an implementation your class is no longer abstract, and you must not use = 0 in your method declaration.
I want to make an abstract class in c++ with a single, but with some default implementation.
so that every class that inherits it will have default behavior but you cant create an instance of the base class.
but if i mark foo as pure virtual, I can't add an implementation to it.
class Base
{
public:
virtual void foo() =0; //Now I can't add foo implementation
};
My solution was to not have it as a pure virtual, and just hide the constructor.
I'm wondering if its possible to mark the class as pure, but still have some implementation?
You can add an implementation to a pure virtual function. Classes that derive can use the default implementation by explicitly invoking the base-class-method.