Access to the function that I want to use only in the derived class

I have a base class Base and several derived classes: Derived1, Derived2, and Derived3.

I would like to have the funcOne function in all of them so that I can access it regularly as follows:

Base* d1 = new Derived1();
Base* d2 = new Derived2();
Base* d3 = new Derived3();

d1->funcOne();
d2->funcOne();
d3->funcOne();

but I would like to have the funcTwo function ONLY in the Derived1 class. The problem is that I want to access it like this:

d1->funcTwo();

Is it possible to do this in some way, besides creating a virtual funcTwo in the base class with some kind of implementation, for example

void funcTwo(){ cout << "There is no funcTwo for this class" << endl; }

And another implementation only for Derived1 class?

Thank!

+4
source share
5 answers

You have two main options that I can think of.

funcTwo , . , , , , -, funcTwo Base, Derived2 Derived3. , API , , , . :

class Base() {virtual void funcTwo() {throw runtime_error("This should not be called");};
Base *d1 = new Derived1;
Base *d2 = new Derived2;
d1->funcTwo(); //fine
d2->funcTwo(); //compiles even though it doesn't make semantic sense, throws an exception

funcTwo Derived1. Derived1, , dynamic_cast, . , Base:: funcTwo , , .

Base *b = new Derived1;
Derived1 *d1 = new Derived1;
Base *d2 = new Derived2;
d1->funcTwo(); //fine
if ((d1 = dynamic_cast<Derived1*>(b)) d1->funcTwo(); //fine
if ((d1 = dynamic_cast<Derived1*>(d2)) d1->funcTwo(); //funcTwo is not called, no errors
b->funcTwo(); //fails to compile
+3

- , funcTwo [...]

, , Base*.

:

Derived1 *d1 = new Derived1(); // not treated as a base*
Base* b1 = d1;
Base* b2 = new Derived2();
Base* b3 = new Derived3();

d1->funcTwo(); // not treated as a base*
b1->funcOne();
b2->funcOne();
b3->funcOne();

( , ):

void CallFunc2(Base* b) {
    if(auto d = dynamic_cast<Derived1*>(b))
        d->funcTwo();
}

:

Base* b1 = new Derived1();
Base* b2 = new Derived2();
Base* b3 = new Derived3();
CallFunc2(b1); // will call Derived1::funcTwo
CallFunc2(b2); // will do nothing
CallFunc2(b3); // will do nothing
+1

, - Base , , , static_cast:

Base* b = new Derived;
static_cast<Derived*>(b)->func2();  // Call function only available in `Derived`

, , b Derived, undefined.

. , , -, .

0

, dynamic_cast. Base - Derived1, , funcTwo(). , .

dynamic_cast . , , , , , .

, , .

, .

Base * b = getBasePtr(); // I don't know which one I got
Derived1 * d1 = dynamic_cast< Derived1 * >( b );
if( d1 )
    d1->func2();
0

, , , .

class Base {
public:
  virtual ~Base() {}
  virtual void func1() = 0;
};

class Derived1 : public Base {
public:
  virtual ~Derived1() {}
  virtual void func1() { std::cout << "Derived1::func1" << std::endl; }
  void func2() { std::cout << "Derived1::func2" << std::endl; }
};

class Derived2 : public Base {
public:
  virtual ~Derived2() {}
  virtual void func1() { std::cout << "Derived2::func1" << std::endl; }
};

void func2(Base& b) {
  Derived1* d = dynamic_cast<Derived1*>(&b);
  if (d) d->func2();
}


void f() {
  Base* b1 = new Derived1;
  Base* b2 = new Derived2;

  func2(*b1);
  func2(*b2);
}

This approach will cost you dynamic_cast, but keep your search in vtable, and also provide you with the desired behavior you were looking for.

-1
source

All Articles