gpt4 book ai didi

C++ 继承和访问 protected 基类成员 : is doing it Java-style a bad idea?

转载 作者:太空狗 更新时间:2023-10-29 19:39:22 24 4
gpt4 key购买 nike

不幸的是,我主要在 Java 的背景下学习类设计和设计模式;因此,有时我很难将熟悉的模式转换为 C++。

假设我们想要一个基类,其功能由子类扩展。在 Java 中,我们会做这样的事情:

public class BaseClass<T> {
//T is used here
protected int foo = 0;
}

public class DerivedClass<T> extends BaseClass<T> {
public void incr_foo() {
++foo;
}
}

我直接翻译成 C++:

template<class T>
class BaseClass {
protected:
size_t foo = 0;
//T is used here
};

template<class T>
class DerivedClass : public BaseClass<T> {
public:
void incr_foo() {
++(this->foo);
}
};

由于“ protected ”的 C++ 语义与 Java 语义不同,我们需要使用类似“this->foo”的方法来访问基类的 protected 成员。

编辑:如果我们只使用“++foo”,编译器会给出错误:“使用未声明的标识符 foo”。

编辑结束

如果您需要访问基类的多个成员,这可能会有点乏味并且读起来不太好。

这是一个好的设计决策吗?如果没有,有什么更好的方法可以实现这一目标?

最佳答案

这与被保护的成员无关;你会得到与公共(public)成员完全相同的错误。

真正的原因是涉及模板。更具体地说,您的类模板有一个依赖于模板参数的基类。这意味着在解析模板时,编译器将不会(无法)查看该基类以查找使用不合格的继承成员。这是有道理的:当模板被解析时,模板参数值是未知的,因此编译器不知道基类将有哪些成员(记住存在部分和全部特化!)。

为了克服这个问题,您必须以某种方式告诉编译器名称 foo取决于模板参数(它是一个从属名称)。一旦这样做,编译器在解析模板时将不会尝试解析它;它将推迟解析,直到模板被实例化。那时,模板参数是已知的,因此可以检查基类。

您可以通过三种方式将成员名称标记为依赖:

  1. 通过this引用名称,正如您所做的那样:this->foo

  2. 通过基类限定引用名称:BaseClass<T>::foo

  3. 将名称带入派生类的范围:

    template<class T>
    class DerivedClass : public BaseClass<T> {
    protected:
    using BaseClass<T>::foo; // from this point on, `foo` is a dependent name
    public:
    void incr_foo() {
    ++foo; // works fine now
    }
    };

关于C++ 继承和访问 protected 基类成员 : is doing it Java-style a bad idea?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23390053/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com