简体   繁体   中英

C++ Inheritance problem

I have a class as follows:

Class A
{
   virtual int doSomethingCool() = 0;
};

Class B : public A
{
  int doSomethingCool();
};

Now the problem likes , I have a set of classes whcih are dependent on A as interface. I need to change the prototype of the function for one of the derived classes. ie i need to pass it a parameter.

Class C: public A
{
 int doSomethingCool(int param);
};

Any suggestions how i can achieve this ?

No, you don't need to add it to the base class.

class A
{
public:
  virtual int doSomethingCool() = 0 {}
};

class B : public A
{
public:
  int doSomethingCool() {return 0;}
};

class C: public A
{
private:
  int doSomethingCool(); // hide base class version!
public:
  int doSomethingCool(int param) {return param;}
};

You can still call doSomethingCool() if done through a base class pointer:

C c;
//c.doSomethingCool (); // doesn't work, can't access private member
c.doSomethingCool (42);
A &a = c;
a.doSomethingCool ();
//a.doSomethingCool (42); // doesn't work, no member of A has that signature

Add it to the interface and default it to call the existing method. You don't have to do the default but don't make it pure otherwise all derived classes will have to implement. It might be better to leave it undefined or to throw. Depends on what you want to achieve.

class A 
{ 
public:
   virtual int doSomethingCool() = 0; 
   virtual int doSomethingCool(int param) {doSomethingCool()}; 
};

Make the function doSomethingCool() take the int parameter in A .

class A
{
public:
    virtual void doSomethingCool(int param) = 0;
};

There's no problem. You can do it. The only caveat is that it will not be treated as an override of the base class virtual function.

class A 
{ 
public:
   virtual void doSomethingCool() = 0; 
};

class B : public A 
{
public:
   void doSomethingCool(); 
}; 

class C: Public A 
{ 
public:
   void doSomethingCool(int param); 
}; 


int main(){}

So while technically possible, you may really want to relook at the design of your interface class A.

One option may be to provide a default argument to A::doSomethingCool

virtual void doSomethingCool(int = 0) = 0;

This isn't syntactically correct C++.

No you can't change a prototype. How would it be used? What would be the value of the param if the non-parametric version would be called?

I would have introduced another, more specific, interface:

struct A
{
  virtual int doSomethingCool() = 0;
};

struct A_specific : A
{
  virtual int doSomethingCoolWithThis(int i) = 0;
};

class ConcreteA : public A
{
  int doSomethingCool() { return 0; }
};

class ConcreteA_specific : public A_specific
{
  int doSomethingCool() { return 0; }
  int doSomethingCoolWithThis(int param) { return param; }
};

Then I would program to the correct interface:

int main()
{
   const A& a1 = ConcreteA();
   const A_specific& a2 = ConcreteA_specific();

   a1.doSomethingCool();
   a2.doSomethingCool();
   a2.doSomethingCoolWithThis(2);
}

Just to give you another idea ;-)

Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM