1

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. i.e. i need to pass it a parameter.

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

Any suggestions how i can achieve this ?

3
  • I have simplified with pseudo code. Commented Nov 26, 2010 at 11:47
  • 2
    If a second class needs something different, that means either it's a different interface or the initial interface is wrong. Commented Nov 26, 2010 at 11:49
  • Declare a parameter with a default value in doSomethingCool in class A. Commented Nov 26, 2010 at 11:59

6 Answers 6

2

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
Sign up to request clarification or add additional context in comments.

Comments

1

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()}; 
};

1 Comment

Note that class C would still have to implement the parameterless doSomethingCool() pure virtual function or you won't be able to create instances of C.
0

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

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

2 Comments

That would break the dependencies of other classes on A.
@Ricko: Yeah, but if you change the parameter list of class C it won't override the method - it hides it. If you intend to override the doSomethingCool() method from class A in class C, it won't do what you think it does. And since class A is abstract, you won't be able to create instances of C since you haven't implemented the parameterless doSomethingCool() yet.
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;

2 Comments

That doesn't override the function in the base class, it hides it, which I'm pretty sure is not what the OP intended.
I would add in your answer that derived classes should not modify default arguments of base class virtual functions, or don't provide default arguments in the first place.
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?

Comments

0

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!

Comments

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.