Почему правило правильности const не работает для встроенных библиотек? - PullRequest
1 голос
/ 09 марта 2019

Существует правило о методах const.Если метод const, и мы пытаемся использовать другую функцию в том же методе, значит, он также должен быть const.В противном случае у нас будет ошибка компиляции.Я пытался найти объявление функции abs () в библиотеке math.h, и вот что я нашел: Объявления abs () Это означает, что функция abs () не const, но когдаЯ использую его внутри метода const. У меня нет ошибки компиляции.Может кто-нибудь объяснить, почему это так?

class D:public B,C
{
public:
    D()
    {
        cout<<"This is constuctor D"<<endl;
    }

    int fun3() const;

    ~D()
    {
         cout<< "Destructor D"<<endl;
    }
};

int D::fun3() const
{
    int x=-3;

    return abs(x);
}

Ответы [ 4 ]

3 голосов
/ 09 марта 2019

Для начала отучись от того, что ты думаешь, что знаешь. Давайте посмотрим, что значит быть членом const.

class D {
public:
    int fun2();
    int fun3() const;
};

Что это заявляет? Существует класс под названием D. Существует две функции-члена fun2 и fun3, каждая из которых принимает скрытый параметр this и никаких других параметров.

Держись! Скрытый параметр? Ну да. Вы можете использовать this внутри функции; его ценность должна исходить откуда-то. Все нестатические функции-члены имеют этот скрытый параметр. Однако не все нестатические функции-члены имеют одинаковый тип скрытого параметра. Если бы я показывал скрытый параметр, объявления выглядели бы следующим образом:

int D::fun2(D * this);
int D::fun3(const D * this);

Обратите внимание, как const существует внутри этой псевдо-декларации? Это эффект объявления const функции-члена: this указывает на объект const, а не на const объект.

Теперь вернемся к вопросу. Может ли fun3 позвонить fun2? Ну, fun3 передаст свой this указатель (указатель на const-объект) на fun2, который ожидает указатель на объект. Это означало бы потерю константности, поэтому это не разрешено.

Может ли fun3 позвонить abs? Ну, fun3 передаст целое число в abs. Здесь нет проблем. Проблема заключается в потере постоянства this. Пока вы этого избегаете, у вас все хорошо.

3 голосов
/ 09 марта 2019

Здесь недопонимание относительно ограничения const функций-членов.

A const функция-член может вызывать любую функцию, которая ей нужна, при условии, что она не изменяет состояние объекта.,Таким образом, fun3() прекрасно компилируется, поскольку не изменяет переменную-член и не вызывает неконстантные функции-члены для одного и того же объекта.

Важное примечание: public B,C может быть не тем, что вы думаете: это означает, что D наследует публично от B и конфиденциально от C. Если вы хотите, чтобы он наследовалпублично из C вы должны заявить public B, public C.

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

Рассмотрим это

#include <iostream>

int f(int num) { return num+1; }
int fr(int& num) { return num+1; }
int fcr(const int& num) { return num+1; }

class D
{
public:
    int value= 0;

public:
    void f1() { value++; }
    int f2() const { return value; }
    int f3() { return value; }
    static void f4() { std::cout << "Hello" << std::endl; }
    void f5() const;
};

void D::f5() const
{
    // Prohibited:
    // f1(); // modifies this
    // f3(); // might modify this
    // value++; // modifies this->value, thus modifies this
    // value= 2; // modifies this->value, thus modifies this
    // value= abs(value); // modifies this->value, thus modifies this
    // fr(value); // takes value by reference and might modify it
    // 
    // Permitted:
    f2(); // const function, does not modify this
    std::cout << value << std::endl; // independent function, does not modify this; read access to this->value is const
    std::cout << abs(value) << std::endl; // independent function, does not modify this; read access to this->value is const
    f4(); // static function, does not modify this
    f(value); // function, does not modify this; takes value as read only (makes copy)
    fcr(value); // function, does not modify this; takes value as read only by reference

    D otherObject;
    otherObject.f1(); // modifies otherObject (non const), does not modify this
}

int main()
{
    const D d;
    d.f5();
}

Всякий раз, когда вы вызываете функцию-член, например f4() внутри f5(), вы передаете неявный указатель this, эквивалентный this->f4(). Внутри f5(), как и const, это не тип D*, а const D*. Таким образом, вы не можете сделать value++ (эквивалентно this->value++ для const D*. Но вы можете позвонить abs, printf или что-то еще, что не займет this и попытается изменить его).

Когда вы берете this->value, если this тип равен D*, это тип int, и вы можете изменить его. Если вы сделаете то же самое с const D*, его тип станет const int, вы не сможете изменить его, но сможете скопировать и получить доступ к нему как к справочнику const для чтения.

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

const, применяемое к методу, означает, что указатель this, то есть указатель на экземпляр, на котором работает метод, равен const.Это означает, что он не может изменять поля и может только вызывать const методы для него , не в целом.

Вызов бесплатной функции вполне приемлем, или даже вызов не- *Метод 1009 * для другого объекта того же класса, если такой объект не является const.

...