0

I not sure how to ask this but basically i pass a base class as an parameter and if the argument is a derived class from the base class i want to be able to access properties only in the derived class

class A{
public:
  bool isB = false; 
  int x = 69;
}
class B : public A{
public:
  bool isB = true;
  int y = 420;
}
void Print(A c){
  if (c.isB)
    cout << c.y << endl; //this will error as the class A has no y even though i will pass class B as an argument
  else
    cout << c.x << endl;
}

A a;
B b;

Print(a);
Print(b);
MrCheese
  • 1
  • 1
  • Your `Print()` function is [slicing](https://stackoverflow.com/questions/274626/) the input parameter, so there is no possible way to get a `B` object into it. You need to pass the parameter by pointer (`A*`) or reference (`A&`) instead. Then `Print()` can use `dynamic_cast` to access members of `B`. But this is not a good design for this situation. You should add a virtual `print()` method to `A` for `B` to override, as [this answer](https://stackoverflow.com/a/70189593/65863) suggests. – Remy Lebeau Dec 01 '21 at 19:45

2 Answers2

3

My recommendation is that you use polymorphism by creating a virtual "print" function that your global Print function calls:

class A
{
    int x = 69;

public:
    virtual ~A() = default;  // Needed for polymorphic classes

    virtual void print(std::ostream& out) const
    {
        out << x;
    }
};

class B : public A
{
    int y = 420;

public:
    void print(std::ostream& out) const override
    {
        out << y;
    }
};

void Print(A const& o)
{
    o.print(std::cout);
    std::cout << std::endl;
}

int main()
{
    A a;
    B b;

    Print(a);
    Print(b);
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
-1

You need to define a virtual function "bool amIaB()" in both base and derived class that returns "isB".

Mark Lavin
  • 1,002
  • 1
  • 15
  • 30
  • 1
    While this would work, it's definitely a design smell. The base class should not need to know this kind of detail about its children. – 0x5453 Dec 01 '21 at 18:41
  • This wouldn't work anyway, as `y` would still not exist in `A` for `Print()` to access. `Print()` would have to use `dymamic_cast` to cast `A` into `B` in order to access `y`. Otherwise, a better choice is to add a `virtual` method to `A` to return/print `x`, and have `B` override that method to return/print `y` instead, then `Print()` can call that method on the given `A` regardless of its actual class type. – Remy Lebeau Dec 01 '21 at 19:53