2015-12-04 3 views
0

Мне любопытно, почему компилятор не жалуется, если я передаю const-указатель на не-const-указатель в качестве параметра в конструкторе класса, который сам , что, конечно же, при времени строительства не const.const-указатель на не-const-указатель в конструкторе

#include <iostream> 

class A 
{ 
public: 
    A(int* v) : v(v) {} 

    int* v; 
}; 

class B 
{ 
public: 
    B() : o(23), v(&o) {} 

    const A cc() const 
    { 
     return A(v); //expected const to non-cosnt error here, but seems valid 
    } 

    int o; 
    int* v; 
}; 

int main() { 
    B b; 
    const B* bc = &b; 

    A a = bc->cc(); 

    *(a.v) = 25; // here I'm changing an originally const value 

    std::cout << b.o << std::endl; 

    return 0; 
} 

с определением CC() как константы я ожидал линию, где возвращаемое значение инициализируется сообщение об ошибке о преобразовании константного к неконстантному. Скомпилированный фрагмент кода прекрасно компилируется, и в конце я получаю вывод «25» даже так, чтобы он был const.

+1

Не возвращайте [const objects] (http://stackoverflow.com/questions/12051012/should-i-return-const-objects) –

+0

И, кстати, вы не передаете указатель на конструктор 'A' где угодно ... –

+0

Память, на которую указывает' v' в 'B', не' const' (и может быть потому, что конструктор, естественно, не является '' const ', где 'o' также не const). Внутри 'cc'' это' const B * ',' o' is 'const int' и' v' is 'int * const'. Члены являются постоянными, но память, на которую указывает 'v', еще не является (будет означать' int const * const'). Однако указатель никогда не изменяется внутри 'cc', а копируется в' A'. – Pixelchemist

ответ

0

const Незнание объекта не распространяется на const Несущий элемент указателя. Указатель становится const, но указатель остается не const. Даже если указатель равен const, вы можете легко получить указатель не const, просто скопировав указатель, что и происходит, когда указатель передается по значению.

2

Конструктор A ожидает копию указателя вместо ссылки. Абсолютно законно копировать int * const в int*. Поэтому ошибка не возникает.

Вы должны использовать ссылки вместо указателей, если хотите последовательное поведение относительно константы. Кстати, возвращение объектов const - плохая идея.

1

Вы вводите в заблуждение int const* (или const int*) и int* const.

Копирование объекта const в новый объект const новый объект в порядке, является ли этот объект указателем или нет. Это все, что вы здесь делаете; сам указатель const (это int* const), поэтому вы можете в значительной степени сделать то, что вам нравится, с его копией.

Что не ОК копирования int const* в int*, потому что теперь вы говорите, вещь на который указывает на магически потеряла свою const -Защита.

+0

Вы правы, я это сделал. Ожидаемый 'int * const', но на самом деле это' int const * 'внутри cc(). Благодарю. PS: В вашем ответе есть опечатка. Вы используете 'int * const'but, пишет' int const * '. – Davidius

+0

@Davidius: Где опечатка? –

+0

_ "Ожидаемый' int * const', но на самом деле это 'int const *' внутри cc(). "_ Нет! Неправильно! Вы [видимо] ожидали 'int const *', но на самом деле это 'int * const'. –

Смежные вопросы