-1

How to change the type of a inherited variable in the derived class? I have the following classes:

class Position;
class StonePosition;

class Position {
public:
    Position() {}
};

class StonePosition : public Position {
    int count;
public:
    StonePosition(const int count) { this->count = count; }
    int getCount() { return this->count; }
    void setCount(int count) { this->count = count; }
    friend ostream& operator<<(ostream&, StonePosition);
};

class Board {
protected:
    Position* crrPos;
public:
    Board() { }
    Position* getCrrPos() { return crrPos; }
    void setCrrPos(Position* pos) { crrPos=pos; }
};

class StoneBoard : public Board {
public:
    StoneBoard(const int &count) { this->crrPos=new StonePosition(count); } //<----------------
    StonePosition* getCrrPos() { return (StonePosition*)crrPos; }
    void setCrrPos(StonePosition* pos) { crrPos=pos; }
};

Place in which the problem is marked by an arrow. I need to change the type of a variable from Position to StonePosition in the StoneBoard class. I found an option that can be used upcasting, but it works only within a single method, and I need to change the variable for the entire class.

The problem was solved, look at my answer.

Nawy
  • 13
  • 1
  • 5
  • 3
    `template class TBoard { ..}` might help. – Jarod42 Jun 10 '16 at 18:17
  • 1
    c++ is not that flexible. You can't change the type of a variable. That is why `Templates` existed https://en.wikipedia.org/wiki/Template_(C%2B%2B) – Khalil Khalaf Jun 10 '16 at 18:19
  • Why do you need to change the type? It seems like you could just `dynamic_cast` into a `StonePosition` whenever you needed one (as you did with `getCrrPos` – lcs Jun 10 '16 at 18:20
  • @lcs because I need to change the value of the variable Position on StonePosition in the class StoneBoard – Nawy Jun 10 '16 at 18:26
  • @Nawy `dynamic_cast` is used to safely cast a parent type pointer to a child type pointer. Don't use C style casts. They're unsafe. – Rob K Jun 10 '16 at 20:43

2 Answers2

0

The variable "crrPos" is not of type Position it is of type pointer to Position and this is significant because a pointer to Position can point to a Position or a class derived from Position without losing anything.

If you design your classes well, and make use of virtual functions, you can usually avoid the need to upcast entirely.

#include <iostream>

class Base {
public:
    virtual void foo() { std::cout << "Base::foo()\n"; }
    virtual bool isDerived() const { return false; }
};

class Derived : public Base {
public:
    void foo() override { std::cout << "Derived::foo()\n"; }
    bool isDerived() const { return true; }
};

int main() {
    Base* crrPos = new Derived;
    crrPos->foo();
    bool isDerived = crrPos->isDerived();
    std::cout << isDerived << '\n';
    delete crrPos;
}

Live demo: http://ideone.com/UKcBaA

kfsone
  • 23,617
  • 2
  • 42
  • 74
  • Well, with the pointer at me too a problem. For example a pointer to a class Position does not know about the existence of the variable count. – Nawy Jun 10 '16 at 19:08
-2

The problem has been solved, I just use the projection ((StonePosition*)Position*):

#include <iostream>
using namespace std;
class Position;
class StonePosition;

class Position {
public:
    Position() {}
};

class StonePosition : public Position {
    int count;
public:
    StonePosition(const int count) { this->count = count; }
    int getCount() { return this->count; }
    void setCount(int count) { this->count = count; }
    friend ostream& operator<<(ostream&, StonePosition);
};
template <typename TPos> class TBoard { 
protected:
    TPos* crrPos;
public:
    TBoard() { }
    TPos* getCrrPos() { return crrPos; }
    void setCrrPos(TPos* pos) { crrPos=pos; }
};
class Board {
protected:
    Position* crrPos;
public:
    Board() { }
    Position* getCrrPos() { return crrPos; }
    void setCrrPos(Position* pos) { crrPos=pos; }
};

class StoneBoard : public Board {
public:
    StoneBoard(const int &count) { this->crrPos=new StonePosition(count); } 
    Position* getCrrPos() { return crrPos; }
    void setCrrPos(Position* pos) { crrPos=pos; }
};

int main(){
    StoneBoard s(7);
    cout<<((StonePosition*)s.getCrrPos())->getCount();//<----right here
    system("pause");
    return 0;
}

And its working nice :)

Nawy
  • 13
  • 1
  • 5