I want to design a parent class
//Parent.h
class Parent {
private:
int currentId;
static int getIdSquare(); //Just random function for simplicity
}
//Parent.cpp
#include "Parent.h"
int Parent::getIdSquare() { return this->currentId * this->currentId };
Of course this won't work! because you cannot access non-static variable in static function but hold on.
I want my child class to be like this
//Child.h
#include "Parent.h"
class Child : public Parent {
private:
static int index;
};
//Child.cpp
#include "Child.h"
int Child::index = 5;
So that in main when I call Child::getIdSquare(); I will get 25. And I should not be able to call Parent::getIdSquare() because its private. How do I go on about creating something like. This is a non-working code just to illustrate the concept. So if I make another child class i can specified the index in its own body. I want to call the method statically.
Please help me figure out this puzzle!
It sounds like what you are after is really a virtual static function. Unfortunately, that doesn't exist in C++.
Also, Child::getIdSquare() will also be private, and inaccessible in main().
If you need to statically pass a value from a child class to its parent, you may need to do it during the inheritance itself via a template argument.
template <int id>
class Parent
{
public:
static int getIdSquare() { return id * id; }
}
class Child : public Parent<5>
{
}
Then Child::getIdSquare() will return 25, as required. It doesn't get around the fact that you want Parent::getIdSquare to be private, while making it public in Child though. For that you would need to declare it as private in Parent and then declare it again as public in Child, with an implementation of return Parent<5>::getIdSquare();
Still not ideal, but it's a relatively vague question, so hard to really find a perfect solution here...
I am not sure I completely understand the question, but I see two alternatives. If you want to implement type-specific properties you could go with traits:
template<typename T>
struct Square {};
class Parent {
};
class Child: public Parent {};
template<> Square<Parent> {
};
template<> Square<Child> {
static constexpr int getIdSquare() {
return 25;
}
};
void foo() {
// this will not compile
//auto id = Square<Parent>::getIdSquare();
// but this will
auto id = Square<Child>::getIdSquare();
}
An alternative design would be to use the template method pattern, but this uses dynamic dispatch. It would look like this:
class Parent {
public:
int getSquareId() {
return currentId() * currentId();
}
private:
virtual int currentId() = 0;
};
class Child: public Parent {
private:
virtual int currentId() override {
return 5;
}
};
Related
I'd like to be able to group similar functions in a class into a group so I don't need to append each name with what it's about.
I've seen this question which says that you can't have namespaces within classes. I've also seen this question which proposes using strongly typed enums. The problem here though, is that I'm not sure whether or not these enums can actually accomodate functions?
The problem contextualised:
class Semaphore
{
public:
void Set(bool State){Semaphore = State;}
bool Get(){return Semaphore;}
void Wait()
{
while (Semaphore)
{
//Wait until the node becomes available.
}
return;
}
private:
bool Semaphore = 0; //Don't operate on the same target simultaneously.
};
class Node : Semaphore
{
public:
unsigned long IP = 0; //IP should be stored in network order.
bool IsNeighbour = 0; //Single hop.
std::vector<int> OpenPorts;
//Rest of code...
};
Currently, NodeClass.Get() is how I can get the semaphore. However this introduces confusion as to what Get() actually gets. I'd like to have something akin to NodeClass.Semaphore::Get(). Otherwise I'd have to have the functions as SemaphoreSet(), SemaphoreGet(), and SemaphoreWait(), which isn't too well organised or nice looking.
I had thought of just having the Semaphore class on it's own, and instantiating it within the other classes, but if I could stick with the inheritance approach, that would be nicer.
So essentially, is it possible to access inherited methods like InheritedClass.Group::Function()?
If you really want to do this, you could force the user to call with the base class name by deleteing the member function in the subclass:
class Base {
public:
void Set(bool) { }
};
class Derived : public Base {
public:
void Set(bool) = delete;
};
int main() {
Derived d;
// d.Set(true); // compiler error
d.Base::Set(true);
}
However, if the semantics of calling Set on the subclass are significantly different than what you'd expect them to be when calling Set on the base class, you should probably use a data member and name a member function accordingly as you've described:
class Base {
public:
void Set(bool) { }
};
class Derived {
public:
void SetBase(bool b) {
b_.Set(b);
}
private:
Base b_;
};
int main() {
Derived d;
d.SetBase(true);
}
I have some classes that describe abilities / behaviours, such as flying, or driving etc. Each of these classes has a specific method that must be called to load some data - For example, Flyable has loadFlyData(), Drivable has loadDriveData(). For each class the method name is unique.
I have many derived classes that may inherit from one or more of these behaviour classes. Each of these derived classes has a method called loadData(), in which we should call all the parent behaviour classes methods such as loadFlyData(), loadDriveData() etc.... Is there a way to automatically generate this method using metaprogramming ? Since there are many derived classes, it may be more maintainable if I can generate these methods using metaprogramming...
Behaviour classes : (An object class may have any of these behaviours, and will have to call that classes "load" method...
class Flyable {
void loadFlyData() {
}
};
class Drivable{
void loadDriveData() {
}
};
All object classes derive from Object:
class Object {
virtual void loadData() {
}
};
A derived class:
class FlyingCar : public Object, public Flyable, public Drivable {
virtual void loadData() override {
// How to automatically generate code so that the next two lines are called:
loadFlyData();
loadDriveData();
}
};
Sure is possible. You'll need however to employ some conventions so the code can be generic. See it live.
#include <iostream>
using namespace std;
struct Flyable{
int loadConcreteData(){
cout << "Flyable\n"; return 0;
}
};
struct Drivable{
int loadConcreteData(){
cout << "Drivable\n"; return 0;
}
};
class Object{
virtual void loadData(){
}
};
template<class ...CS>
struct ConcreteLoader : Object, CS... {
void loadData() override {
int load[] = {
this->CS::loadConcreteData()...
};
}
};
class FlyingCar : public ConcreteLoader<Flyable,Drivable>{
};
int main() {
FlyingCar fc;
fc.loadData();
return 0;
}
Changes that need mentioning:
The return type of each concrete Load function had to be changed. This is to facilitate the "array trick" in expanding the parameter pack.
The names of all the load functions are the same, again for the same reason.
Reason (1) may become obsolete once c++17 and fold expressions roll out.
You can make a free function loadXData() that will become a noop if your class isn't X:
namespace detail
{
void loadFlyData(Flyable* ptr) { ptr->loadFlyData(); }
void loadFlyData(...) {}
void loadDriveData(Drivable* ptr) { ptr->loadDriveData(); }
void loadDriveData(...) {}
}
class FlyingCar : public Object, public Flyable, public Drivable{
public:
virtual void loadData()override{
//How to automatically generate code so that the next two lines are called:
detail::loadFlyData(this);
detail::loadDriveData(this);
}
};
demo
Though I think using a common name loadData and just calling it for all variadic parents might be preferable:
template<typename... Policies>
struct ComposedType : Object, Policies...
{
virtual void loadData() override {
int arr[] = {
((void)Policies::loadData(), 0)...
};
(void)arr;
}
};
using FlyingCar = ComposedType<Drivable, Flyable>;
demo
The above loadData could be simplified in C++1z:
virtual void loadData() override {
((void)Policies::loadData(), ...);
}
demo
I need several C++ classes to have a static method "register", however the implementation of register varies between those classes.
It should be static because my idea is to "register" all those classes with Lua (only once of course).
Obviously I can't declare an interface with a static pure virtual function. What do you guys suggest me to do ? Simplicity is welcome, but I think some kind of template could work.
Example of what I would like to achieve
class registerInterface
{
public:
static virtual void register() = 0; //obviously illegal
};
class someClass: public registerInterface
{
static virtual void register()
{
//I register myself with Lua
}
}
class someOtherClass: public registerInterface
{
static virtual void register()
{
//I register myself with Lua in a different way
}
}
int main()
{
someClass::register();
someOtherClass::register();
return 0;
}
Based on how you've described the problem, it's unclear to me why you even need the 'virtual static method' on the classes. This should be perfectly legal.
class SomeClass {
static void register(void) {
...
}
}
class SomeOtherClass {
static void register(void) {
...
}
}
int main(int argc, char* argv[]) {
SomeClass::register();
SomeOtherClass::register();
return 0;
}
Drop the RegisterInterface, I don't think you need it.
If it helps, you could take Hitesh's answer, and add:
struct luaRegisterManager {
template <typename T>
void registrate() {
T::registrate();
// do something else to record the fact that we've registered -
// perhaps "registrate" should be returning some object to help with that
}
};
Then:
int main() {
luaRegisterManager lrm;
lrm.registrate<someClass>();
lrm.registrate<someOtherClass>();
}
More generally, if you want to introduce any dynamic polymorphism in C++, then you need an object, not just a class. So again, perhaps the various register functions should be returning objects, with some common interface base class registeredClass, or classRegistrationInfo, or something along those lines.
Could provide an example of what you feel it is that you need dynamic polymorphism for? Hitesh's code precisely matches your one example, as far as I can see, so that example must not cover all of your anticipated use cases. If you write the code that would be using it, perhaps it will become clear to you how to implement it, or perhaps someone can advise.
Something else that might help:
#include <iostream>
#include <string>
#include <vector>
struct Registered {
virtual std::string name() = 0;
virtual ~Registered() {}
Registered() {
all.push_back(this);
}
static std::vector<Registered*> all;
};
std::vector<Registered*> Registered::all;
typedef std::vector<Registered*>::iterator Iter;
template <typename T>
struct RegisteredT : Registered {
std::string n;
RegisteredT(const std::string &name) : n(name) { T::registrate(); }
std::string name() { return n; }
// other functions here could be implemented in terms of calls to static
// functions of T.
};
struct someClass {
static Registered *r;
static void registrate() { std::cout << "registering someClass\n"; }
};
Registered *someClass::r = new RegisteredT<someClass>("someClass");
struct someOtherClass {
static Registered *r;
static void registrate() { std::cout << "registering someOtherClass\n"; }
};
Registered *someOtherClass::r = new RegisteredT<someOtherClass>("someOtherClass");
int main() {
for (Iter it = Registered::all.begin(); it < Registered::all.end(); ++it) {
std::cout << (*it)->name() << "\n";
}
}
There are all sorts of problems with this code if you try to split it across multiple compilation units. Furthermore, this kind of thing leads to spurious reports from memory leak detectors unless you also write some code to tear everything down at the end, or use a vector of shared_ptr, Boost pointer vector, etc. But you see the general idea that a class can "register itself", and that you need an object to make virtual calls.
In C++ you usually try to avoid static initialisation, though, in favour of some sort of setup / dependency injection at the start of your program. So normally you would just list all the classes you care about (calling a function on each one) rather than try to do this automatically.
Your intentions are noble, but your solution is inkling towards "overengineering" (unless I am missing an obvious solution).
Here is one possibility: You can use the Virtual Friend function idiom For example,
class RegisterInterface{
friend void register(RegisterInterface* x){x->do_real_register();}
protected:
virtual void do_real_register();
}
class Foo : public RegisterInterface{
protected:
virtual void do_real_register(){}
};
class Bar : public RegisterInterface{
protected:
virtual void do_real_register(){}
};
int main(int argc, char* argv[]) {
BOOST_FOREACH(RegisterInterface* ri, registered_interfaces)
{
register(ri);
}
return 0;
}
I know you've already accepted an answer, but I figured I would write this up anyway. You can have self-registering classes if you use some static initialization and the CRTP:
#include <vector>
#include <iostream>
using namespace std;
class RegisterableRoot // Holds the list of functions to call, doesn't actually need
// need to be a class, could just be a collection of globals
{
public:
typedef void (*registration_func)();
protected:
static std::vector<registration_func> s_registery;
public:
static void do_registration()
{
for(int i = 0; i < s_registery.size(); ++i)
s_registery[i]();
}
static bool add_func(registration_func func) // returns something so we can use it in
// in an initializer
{
s_registery.push_back(func);
return true;
}
};
template<typename RegisterableType> // Doesn't really need to inherit from
class Registerable : public RegisterableRoot // RegisterableRoot
{
protected:
static const bool s_effect;
};
class A : public Registerable<A> // Honestly, neither does A need to inherit from
// Registerable<T>
{
public:
static void Register()
{
cout << "A" << endl;
}
};
class B : public Registerable<B>
{
public:
static void Register()
{
cout << "B" << endl;
}
};
int main()
{
RegisterableRoot::do_registration();
return 0;
}
std::vector<RegisterableRoot::registration_func> RegisterableRoot::s_registery;
template <typename RegisterableType> // This is the "cute" part, we initialize the
// static s_effect so we build the list "magically"
const bool Registerable<RegisterableType>::s_effect = add_func(&RegisterableType::Register);
template class Registerable<A>; // Explicitly instantiate the template
// causes the equivalent of
// s_registery.push_back(&A::Register) to
// be executed
template class Registerable<B>;
This outputs
A
B
although I wouldn't rely on this order if I were you. Note that the template class Registerable<X> need not be in the same translation unit as the call to do_registration, you can put it with the rest of your definition of Foo. If you inherit from Registerable<> and you don't write a static void Register() function for your class you'll get a (admittedly probably cryptic) compiler error much like you might expect if there really was such a thing as "static virtuals". The "magic" merely adds the class specific function to the list to be called, this avoids several of the pitfalls of doing the actual registration in a static initializer. You still have to call do_registration for anything to happen.
How about this way? Define an interface class:
// IFoobar.h
class IFoobar{
public:
virtual void Register(void) = 0;
}
Then define the class that handles the register..
// RegisterFoobar.h
class RegisterFoobar{
public:
// Constructors etc...
IFoobar* fooBar;
static void RegisterFoobar(IFoobar& fubar){
foobar = &fubar;
}
private:
void Raise(void){ foobar->Register(); }
}
Now, then define another class like this
// MyFuBar.h
class MyFuBar : IFoobar{
public:
// Constructors etc...
void Register(void);
private:
RegisterFoobar* _regFoobar;
}
Call the code like this:
//MyFuBar.cpp
MyFuBar::MyFuBar(){
_regFoobar = new Foobar();
_regFoobar->RegisterFoobar(this);
}
void MyFuBar::Register(void){
// Raised here...
}
Maybe I have misunderstood your requirements...
I have something like this:
class Base
{
public:
static int Lolz()
{
return 0;
}
};
class Child : public Base
{
public:
int nothing;
};
template <typename T>
int Produce()
{
return T::Lolz();
}
and
Produce<Base>();
Produce<Child>();
both return 0, which is of course correct, but unwanted. Is there anyway to enforce the explicit declaration of the Lolz() method in the second class, or maybe throwing an compile-time error when using Produce<Child>()?
Or is it bad OO design and I should do something completely different?
EDIT:
What I am basically trying to do, is to make something like this work:
Manager manager;
manager.RegisterProducer(&Woot::Produce, "Woot");
manager.RegisterProducer(&Goop::Produce, "Goop");
Object obj = manager.Produce("Woot");
or, more generally, an external abstract factory that doesn't know the types of objects it is producing, so that new types can be added without writing more code.
There are two ways to avoid it. Actually, it depends on what you want to say.
(1) Making Produce() as an interface of Base class.
template <typename T>
int Produce()
{
return T::Lolz();
}
class Base
{
friend int Produce<Base>();
protected:
static int Lolz()
{
return 0;
}
};
class Child : public Base
{
public:
int nothing;
};
int main(void)
{
Produce<Base>(); // Ok.
Produce<Child>(); // error :'Base::Lolz' : cannot access protected member declared in class 'Base'
}
(2) Using template specialization.
template <typename T>
int Produce()
{
return T::Lolz();
}
class Base
{
public:
static int Lolz()
{
return 0;
}
};
class Child : public Base
{
public:
int nothing;
};
template<>
int Produce<Child>()
{
throw std::bad_exception("oops!");
return 0;
}
int main(void)
{
Produce<Base>(); // Ok.
Produce<Child>(); // it will throw an exception!
}
There is no way to override a static method in a subclass, you can only hide it. Nor is there anything analogous to an abstract method that would force a subclass to provide a definition. If you really need different behaviour in different subclasses, then you should make Lolz() an instance method and override it as normal.
I suspect that you are treading close to a design problem here. One of the principals of object-oriented design is the substitution principal. It basically says that if B is a subclass of A, then it must be valid to use a B wherever you could use an A.
C++ doesn't support virtual static functions. Think about what the vtable would have to look like to support that and you'll realize its a no-go.
or maybe throwing a compile-time error when using Produce<Child>()
The modern-day solution for this is to use delete:
class Child : public Base
{
public:
int nothing;
static int Lolz() = delete;
};
It helps avoid a lot of boilerplate and express your intentions clearly.
As far as I understand your question, you want to disable static method from the parent class. You can do something like this in the derived class:
class Child : public Base
{
public:
int nothing;
private:
using Base::Lolz;
};
Now Child::Lolz becomes private.
But, of course, it's much better to fix the design :)
I have a class, lets call it A, and within that class definition I have the following:
static QPainterPath *path;
Which is to say, I'm declaring a static (class-wide) pointer to a path object; all instances of this class will now have the same shared data member. I would like to be able to build upon this class, subclassing it into more specialised forms, layering behaviour, and with each class having its own unique path object (but not having to repeat the boring bits like calculating bounding boxes or calling the painting routines).
If I subclass it to create a class F (for example), I want F to use the inherited drawing routines from A, but to use the static (class-wide) path object declared in F. I have tried having the declaration above in the private section (and repeating it in the derived class F), and tried having it in the protected section, all with no joy.
I can sort of see why this is happening:
void A::paint() {
this->path...
is referring to A::path instead of F::path, even when the object is of class F.
Is there an elegant way to get round this, and allow each class to maintain a static path object, while still using drawing code defined in the base class, and having all classes (except perhaps the base class) be real and instantiatable?
Use a virtual method to get a reference to the static variable.
class Base {
private:
static A *a;
public:
A* GetA() {
return a;
}
};
class Derived: public Base {
private:
static B *b;
public:
A* GetA() {
return b;
}
};
Notice that B derives from A here. Then:
void Derived::paint() {
this->GetA() ...
}
You might be able to do a variant on a mix in or Curiously recurring template pattern
#include <stdio.h>
typedef const char QPainterPath;
class Base
{
public:
virtual void paint() { printf( "test: %s\n", getPath() ); }
virtual QPainterPath* getPath() = 0;
};
template <class TYPE>
class Holder : public Base
{
protected:
static QPainterPath* path;
virtual QPainterPath* getPath() { return path; }
};
class Data1 : public Holder<Data1>
{
};
class Data2 : public Holder<Data2>
{
};
template <> QPainterPath* Holder<Data1>::path = "Data1";
template <> QPainterPath* Holder<Data2>::path = "Data2";
int main( int argc, char* argv[] )
{
Base* data = new Data1;
data->paint();
delete data;
data = new Data2;
data->paint();
delete data;
}
I have just run this code in CodeBlocks and got the following:
test: Data1
test: Data2
Process returned 0 (0x0) execution time : 0.029 s
Press any key to continue.
I haven't tested this, but introducing a virtual function:
struct Base {
void paint() {
APath * p = getPath();
// do something with p
}
virtual APath * getPath() {
return myPath;
}
static APath * myPath;
};
struct Derived : public Base {
APath * getPath() {
return myPath;
}
static APath * myPath;
};
may be what you want. Note you still have to define the two statics somewhere:
APath * Base::myPath = 0;
APath * Derived::myPath = 0;
You can use virtual functions to achieve your result. This is probably your cleanest solution.
class A
{
protected:
virtual QPainterPath *path() = 0;
private:
static QPainterPath *static_path; /* Lazy initalization? */
};
QPainterPath *A::path()
{
return A::static_path;
}
class F : public A
{
protected:
virtual QPainterPath *path() = 0;
private:
static QPainterPath *F_static_path; /* Lazy initalization? */
};
QPainterPath *A::path()
{
return F::F_static_path;
}
I know this question has been answered, but there is an other way to set the value of a similar static variable for multiple classes through a helper class and some template specialization.
It doesn't exactly answer the question since it is not connected with subclassing in any way, but I've encountered the same issue and I found a different solution I wanted to share.
Example :
template <typename T>
struct Helper {
static QPainterPath* path;
static void routine();
}
// Define default values
template <typename T> QPainterPath* Helper<T>::path = some_default_value;
template <typename T> void Helper<T>::routine { do_somehing(); }
class Derived {};
// Define specialized values for Derived
QPainterPath* Helper<Dervied>::path = some_other_value;
void Helper<Dervied>::routine { do_somehing_else(); }
int main(int argc, char** argv) {
QPainterPath* path = Helper<Derived>::path;
Helper<Derived>::routine();
return 0;
}
Pros:
clean, compile time initialization
static access (no instantiation)
you can declare specialized static functions too
Cons:
no virtualization, you need the exact type to retrieve the information
You can't "override" static functions, let alone static member variables.
What you need is probably a virtual function. These can only be instance functions, so they will not be accessible without class instance.
You probably don't want static variables to the overriden. Maybe you can store a pointer in your class instead?
class A
{
public:
A() :
path(static_path)
{
}
protected:
A(QPainterPath *path)
: path(path)
{
}
private:
QPainterPath *path;
static QPainterPath *static_path; /* Lazy initalization? */
};
class F : public A
{
public:
F() :
A(F_static_path)
{
}
private:
static QPainterPath *F_static_path; /* Lazy initalization? */
};
If you don't care about the appearance just use A:: or F:: preceding the use of path to choose the correct one, or if you don't like :: name them differently.
Another option is to use a function to tidy this away, e.g. virtual QPainterPath* GetPath() { return A::path; } in A and QPainterPath* GetPath() { return F::path; } in F.
Really though this issue is just about how the code looks rather than what it does, and since it doesn't really alter readability I wouldn't fret about this...