Определить геттер для дочерней переменной класса внутри родителя - PullRequest
0 голосов
/ 09 марта 2020

У меня есть проект, в котором я обращаюсь к нескольким классам, используя указатель на родительский класс. Мне нужно знать, на какой дочерний класс ссылается указатель, поэтому я добавляю отдельный целочисленный идентификационный номер к каждому из них как переменную класса констант.

Мне нужен доступ к этой переменной с помощью указателя, поэтому я написал функцию получения для этой переменной. Поскольку код функции-получателя был бы одинаковым для всех дочерних классов, я попытался определить функцию в родительском классе. Это примерно приводит к коду, найденному ниже:

class Parent {
  public:
    virtual void func();

    // Getter function
    uint8_t getID() {
      return classID;
    }

    // Set ID to a default value
    const uint8_t classID = 0;
};

// One of many child classes
class A: public Parent {
  public:
    void func() {//do something}

    const uint8_t classID = 1;
};

int main(){
    Parent* childPointer = new A;
    uint8_t currentID = childPointer -> getID();
}

Однако выполнение этого привело к тому, что currentID будет равно Parent.classID, а не A.classID.

Создание getID Функция virtual и определение ее в каждом из дочерних классов сделали ее работающей так, как задумано, но это привело бы к частичному повторению кода. Мне было интересно, есть ли способ определить функцию-получатель один раз в классе Parent и заставить ее вернуть правильное значение? Иначе, есть ли более чистый способ сделать это?

1 Ответ

0 голосов
/ 09 марта 2020

В C ++ каждый класс имеет свое собственное пространство имен. В вашем коде у вас есть classID в пространстве имен Parent и classID в пространстве имен A. Таким образом, каждый экземпляр A на самом деле имеет 2 classID. Однако функция getID () видит classID только в пространстве имен Parent. Вот почему он возвращает только 0.

Лучше было бы определить конструкторы, которые будут инициализировать classID в Parent:

#include <cstdint>

class Parent {
  public:
    Parent(): classID(0){}; //Default Parent initializes with 0
    Parent(uint8_t ID): classID(ID){}; //Constructor to be called by children

    virtual void func(){};

    // Getter function
    uint8_t getID() {
      return classID;
    };

    const uint8_t classID;
};

// One of many child classes
class A: public Parent {
  public:
    A(): Parent(1){}; //Every A calls Parent(uint8_t) constructor

    void func() {};//do something

    //const uint8_t classID = 1;  //This is not needed anymore
};

int main(){
    Parent* childPointer = new A;
    uint8_t currentID = childPointer -> getID();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...