C++保护/公共重载

C++ Protected / Public overloads

本文关键字:重载 保护 C++      更新时间:2023-10-16

我有一个这样的类:

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;

非常感谢你的帮助。

=====

感谢大家的解释和解决方案!非常感谢!

返回值时不可能重载。当对象为非常量时,将使用非常量方法。可以通过以下方式指导编译器:

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

或者可能更好的解决方案是让常量方法有不同的名称(例如:ConstV)。或者,您可以添加这个新方法,并将当前方法保留在那里。这种方法在C++0x标准中使用。例如,常量方法cbegin()cend()已添加到标准容器中。

重载解决方案不考虑成员的可访问性,因此选择一个理想的重载候选者,然后检查成员的可存取性,以确定调用是否合法。

现实的解决方法是:

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;

由于foo不是const,编译器正在尝试使用非常数方法。作为一种变通方法,您可以执行以下操作:

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

您已接近解决方案。如果Foo也是const,编译器将选择const函数。

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