#include <iostream>
using namespace std;

class bike {
  public:
		bike ()
		{
			cout << "Bike: no parameters\n";
		}
		bike (int a)
		{
			cout << "Bike: int parameter\n";
		}
		void color(int a,int b)
		{
			cout<<"Inside Bike Color"<<endl;
		}
};

class ducati : public bike {
  public:
		ducati (int a)
		{
			cout << "Ducati: int parameter\n\n";
		}
		void color(int a,int b,int c)
		{
					cout<<"Inside Ducati Color"<<endl;
		}
	};

class honda : public bike {
  public:
	  honda (int a) : bike (a)
      {
    	cout << "honda: int parameter\n\n";
      }

};

int main ()
{
  ducati monster(0);
  ducati *dObj=new ducati(10);
  bike *bObj=&monster;
  bObj->color(10,20,30); //it's showing error at this line. 

  return 0;
}

Please help me out

Dani AI

Generated

Short answer: the compiler is doing lookup and overload resolution on the static type bike*, so a three-argument color that exists only in ducati is invisible there. already pointed out the overload-vs-override root cause. A few practical ways to resolve this, depending on intent:

  • If the goal is polymorphic behavior for the same signature, make the base operation part of the interface (declare bike::color virtual) and override it in ducati. Use override in the derived class and give bike a virtual destructor.

  • If the three-argument function is truly ducati-specific, call it on a ducati object (or safely cast a bike* to ducati* with dynamic_cast and check for null) before invoking the 3-arg overload. Downcasts are runtime checks and should be used sparingly.

  • If calling on a derived object should still let overloads from the base be found, add using bike::color; inside ducati to stop name hiding (otherwise any color declared in ducati hides the base overloads).

Minimal illustration (not a copy of the earlier examples):

class bike {
public:
  virtual ~bike() {}
  void color(int a,int b) { /* base behavior */ }
};

class ducati : public bike {
public:
  using bike::color;          // bring base overloads into scope
  void color(int a,int b,int c) { /* ducati-only behavior */ }
};

bike *b = &monster;
if (ducati *d = dynamic_cast<ducati*>(b))
  d->color(10,20,30);         // safe call to ducati overload

Design guidance: prefer putting operations that clients need into the base interface rather than relying on casts. Use override and a virtual destructor to catch signature mistakes and to keep behavior well-defined.

void color(int a,int b)

Two parameters.

bObj->color(10,20,30);

Three arguments.

I see what you wanted to happen, but it won't work because ducati's version of color() is an overload rather than an override. When looking at the object through a pointer to bike, you can only see the public member functions declared in bike. Since the three parameter version of color() is added in ducati, it's not visible from a pointer to bike even if that pointer points to a ducati object.

You can achieve something similar with judicious constructor parameters, virtual member functions, and polymorphism:

#include <iostream>

using namespace std;

class bike
{
public:
    bike() {
        cout << "bike()\n";
    }
    bike(int a) {
        cout << "bike(int a)\n";
    }
    virtual void color(int a, int b) {
        cout<<"Inside Bike Color"<<endl;
    }
};

class ducati : public bike
{
public:
    ducati(int a): bike(a) {
        cout << "ducati(int a)\n";
    }
    ducati(int a, int c): bike(a) {
        cout << "ducati(int a, int c)\n";
    }
    virtual void color(int a, int b) {
        cout<<"Inside Ducati Color"<<endl;
    }
};

int main()
{
    ducati monster(0, 30);
    bike *bObj = &monster;
    
    bObj->color(10, 20);
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.