Правильное моделирование классов с использованием C ++ и Const

StackOverflow https://stackoverflow.com//questions/22048452

  •  21-12-2019
  •  | 
  •  

Вопрос

Позвольте мне предпочтение тому, что я в основном разрабатываю в C # и разработку C ++, которое я сделал, не полностью использует язык C ++. Сейчас я пытаюсь использовать язык, как это было предназначено, и я вытягиваю волосы с декларациями Const в прошлых аргументах. В прошлом я никогда не использовал их и не взломал свой путь, чтобы заставить их работать с STL.

Мое понимание того, что я бы создал следующую функцию, когда я хочу использовать o так, как отреатно в функции:

void foo(const MyClass* o);
.

Так вот моя проблема ... первый код:

#include <iostream>
#include <string>

using namespace std;

///////////////////////////////////////////////////////////
// Classes are defined in the one file for an easy post.

///////////////////////////////////////////////////////////

class ClassA {
private: // member variables
    string m_name;

public: // constructors
    ClassA(const string& name = "") : m_name{name} {}
    virtual ~ClassA() { }

public: // accessors
    const string& name() const { return m_name; }
    void setName(const string& value) { m_name = value; }   
};

class ClassB {
private: // member variables
    string m_name;
    ClassA m_child;

public: // constructors
    ClassB(const string& name = "") : m_name{name} {}
    virtual ~ClassB() { }

public: // accessors
    const string& name() const { return m_name; }
    void setName(const string& value) { m_name = value; }

    ClassA* child() { return &m_child; }
    void setChild(const ClassA* value) { m_child = *value; }
};

///////////////////////////////////////////////////////////
// Protoptypes are not used to save space for the post.

void doSomethingA(const ClassA* o) {
   cout << "name = " << o->name() << endl << endl;
}

void doSomethingB(const ClassB* o) {
   cout << "name = " << o->name() << endl << endl;
   doSomethingA(o->child());
}

///////////////////////////////////////////////////////////

int main(int argc, char** argv) {
    ClassA a { "My Class A" };
    ClassB b { "My Class B" };


    b.setChild(&a);
    b.child()->setName("My New Name");
    doSomethingB(&b);
    return 0;
}
.

в основном () Compiler (G ++ версия 4.7.2) Balks в Dosomethethetb:

doSomethingA(o->child());
.

с ошибкой: прохождение «Const Classb» как «этот» аргумент «Classa * Classb :: Childa () отбрасывает квалификаторы [-FPERMISSIVE]

Теперь я передаю свои классы для функций в качестве указателей. Я планирую всегда использовать указатели, потому что у меня проблема с вариантами ссылки / указателя. Я выбираю один, указатели и прилипая к нему. Так что Dosomthingta и Dosomethethetb я хочу, чтобы это было const, чтобы сказать программисту, что их класс не изменяется. Но я хочу только одну версию ребенка (), которую я хочу использовать иногда как «только чтение», и другие времена позволяют пользователю изменять данные в дочернем объекте (не лучший метод, я предоставляю это, но есть некоторое использование случаи, где мне это нужно). Я даже попробовал:

doSomethingA(const_cast<const ClassA*>(o->child()));
.

Но это не сработало.

В прошлом я удалил декларации Const в функциях, чтобы сделать что-то вроде этой работы, но теперь я хочу использовать правильный C ++. Помогите пожалуйста.

Это было полезно?

Решение

Вы пытаетесь получить доступ к функции не-постоянной против объекта Const.Вам нужно сделать функцию const:

const ClassA* child() const { return &m_child; }
.

Вы также можете предоставить версию Const и Non-Const:

ClassA* child() { return &m_child; }
const ClassA* child() const { return &m_child; }
.

Таким образом, вы можете вызвать методы не-COND на ClassA, когда у вас есть объект без константа.

Другие советы

попробуйте

ClassA* child() const { return &m_child; }
.

или

const ClassA* child() const { return &m_child; }
.

Чтобы сохранить корректность Const

Кроме того, вам не нужно использовать указатели, если вы не планируете проходить Nulleptr.Таким образом, вы можете сделать следующее:

void doSomethingB(const ClassB& o);

// in class ClassB
const ClassA& child() const { return m_child; }
ClassA& child() { return m_child; }
.

Ссылки все еще одиноки полиморфные вещи так же, как указатели.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top