1

Suppose I have the following code:

class Board
{
  protected:
    std::vector<Piece*> pieces;
}

class ChessBoard : public Board
{
  protected:
    std::vector<ChessPiece*> pieces;

}

I am wanting the derived class to override the protected variable pieces with this new vector, however I am having difficulty with it, and it seems like this is bad practice.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
adammoyle
  • 199
  • 1
  • 13
  • 6
    You can't override *data members*, only *`virtual` methods*. Your `ChessBoard::pieces` member is [*shadowing*](https://en.wikipedia.org/wiki/Variable_shadowing) the `Board::pieces` member. What is your actual *goal* with this code? Please be more specific. – Remy Lebeau May 05 '21 at 23:07
  • 2
    its not bad practice, because it isnt possible. [xy problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) ? Why do you think you need this? – 463035818_is_not_an_ai May 05 '21 at 23:10
  • @RemyLebeau The ChessPiece class is a derived class of Piece and has some member functions that Piece doesn't have. So if I leave pieces as type Piece* I get errors such as "class Piece" has no member function ... – adammoyle May 05 '21 at 23:13
  • 2
    @adammoyle In that case, you would have to either 1) introduce `virtual` methods into `Piece` that `CheckPiece` can override (preferred), or 2) type-cast a `Piece*` to `CheckPiece*` when you need to access `ChessPiece`-specific functionality (less preferred). – Remy Lebeau May 05 '21 at 23:22
  • @RemyLebeau Thank you! Yes, I understand now that solves all my problems. Solved – adammoyle May 05 '21 at 23:27
  • If you find the interface of `ChessPiece` is different enough from `Piece` that you can't use a `ChessPiece` as a `Piece`, the is-a relationship implied by inheritance may not the the right choice. See the [Liskov Substitution Principle](https://stackoverflow.com/questions/56860/what-is-an-example-of-the-liskov-substitution-principle). – user4581301 May 05 '21 at 23:30
  • @user4581301 Yes, unfortunately, I have wasted everyone's time. I simply needed to cast the piece to the type I wanted and it solved everything. The second vector was an attempt to solve that problem but is no longer need. Thank you for the time and effort you put in and sorry for wasting it – adammoyle May 05 '21 at 23:34
  • 2
    You learned something. Time wasn't wasted. That said, see if you can get what you want with `virtual` functions rather than casting. It tends to scale better. – user4581301 May 05 '21 at 23:36
  • @adammoyle: As a note: I find that having "data" classes that use virtual inheritance causes chaos and headaches. Prefer to reserve virtual inheritance for "logic" classes. – Mooing Duck May 05 '21 at 23:42

1 Answers1

5

There is no such thing as "overriding a variable", whether protected or otherwise.

In your example program, the class ChessBoard contains a member sub object pieces and a base sub object Board that contains the member Board::pieces. Thus, there are two vectors inside the object.

Object oriented programming is achieved through virtual functions. You haven't explained what you're trying to do (beyond something that cannot be done) so this is just a guess, but maybe you are looking for covariant return types:

class Board
{
    protected:
        virtual Piece&
        operator[](std::size_t index) = 0;

    public:
        virtual ~Board() = default;
};

class ChessBoard : public Board
{
    std::vector<ChessPiece> pieces;

    protected:
        virtual ChessPiece&
        operator[](std::size_t index) override;
};

Furthermore, if the sub classes have identical base and/or member function implementations except for the types, then you can avoid repetition by using a template.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Yes, this makes sense to me. However, suppose ChessPiece has member functions that Piece doesn't have and thus I can't leave the vector as type Piece* or else I raise errors such as "class Piece" has no member function ... – adammoyle May 05 '21 at 23:22
  • @adammoyle Then change the element type. – eerorika May 05 '21 at 23:23
  • Thank you for putting the effort in I was just being dense. My whole solution was solved by type-casting. Sorry for wasting your time – adammoyle May 05 '21 at 23:32
  • opinionated nitpick: Imho object oriented programming is much more than virtuals and more than inheritance. Runtime polymorphism is achieved through virtual functions. – 463035818_is_not_an_ai May 06 '21 at 11:25
  • 1
    @largest_prime_is_463035818 OOP is certainly more than virtual functions, but they are in my opinion the most essential, core part of OOP. A counter-nitpick: Runtime polymorphism is more than just virtual functions :) – eerorika May 06 '21 at 11:42
  • Interesting. I appreciate different views and opinions (seriously). Unfortunately this isnt the place to discuss. – 463035818_is_not_an_ai May 06 '21 at 11:44