C ++ Защищенные / публичные перегрузки - PullRequest
4 голосов
/ 26 мая 2011

У меня есть такой класс:

class Foo
{
public:
    Foo()
    {
        for(int i = 0; i < 10; ++i)
            v.push_back(i);
    };
    const vector<double>& V() const {return v;};
protected:
    vector<double>& V() {return v;};
private:
    vector<double> v;
};

А потом такой фрагмент кода:

Foo foo;
for(int i = 0; i < (int) foo.V().size(); ++i)
    cout << foo.V().at(i) << endl;

Тем не менее, последний вызывает ошибку компиляции, говоря, что вызов V() является защищенным методом, в то время как я просто пытаюсь читать из него, а не изменять его.

Я попробовал следующее (но безуспешно).

Foo foo;
const vector<double>& test = foo.V();
for(int i = 0; i < (int) test.size(); ++i)
    cout << test.at(i) << endl;

Большое спасибо за вашу помощь.

=====

Спасибо всем за объяснения и решения! Это очень ценится!

Ответы [ 4 ]

5 голосов
/ 26 мая 2011

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

Реалистичный обходной путь:

Foo foo;
Foo const& foo_alias = foo;
for (std::size_t i = 0; i != foo_alias.V().size(); ++i)
    cout << foo_alias.V().at(i) << endl;
5 голосов
/ 26 мая 2011

Невозможно перегрузить возвращаемое значение.Неконстантный метод будет использоваться, когда объект неконстантный.Компилятором можно руководствоваться:

const vector<double>& test = const_cast<Foo const&>(foo).V();

Или, возможно, более удачным решением было бы присвоить константному методу другое имя (например: ConstV).Или вы можете просто добавить этот новый метод и оставить текущий метод там.Этот подход используется в стандарте C ++ 0x.Например, постоянные методы cbegin() и cend() были добавлены в стандартные контейнеры.

2 голосов
/ 26 мая 2011

Поскольку foo не const, компилятор пытается использовать неконстантный метод.В качестве обходного пути вы можете сделать следующее:

    Foo foo;
    const Foo& cFoo = foo;
    for(int i = 0; i < (int) cFoo.V().size(); ++i)
    cout << cFoo.V().at(i) << endl;
1 голос
/ 26 мая 2011

Вы близки к решению.Компилятор выберет функцию const, если Foo также const.

Foo foo;
const Foo& cfoo = foo; 

for(int i = 0; i < (int) cfoo.V().size(); ++i)
    cout << cfoo.V().at(i) << endl; 
...