我在这里有一个旧的代码库,他们使用受保护的成员变量.可以讨论这是否是一个好主意.但是,代码必须与gcc3编译良好.我有一个派生模板类Bar,它使用类模板Foo中的受保护成员x
template <class Something> class Foo {
public:
// stuff...
protected:
some::type x;
}
template <class Something> Bar : Foo<Something> {
public:
void cleanup();
}
Run Code Online (Sandbox Code Playgroud)
在cleanup()的方法声明中,有一些用x完成的事情
template <class Something> void Bar<Something>::cleanup() {
doSomeThingCleanUpLike (x);
}
Run Code Online (Sandbox Code Playgroud)
这不适用于gcc4,虽然它应该与gcc3一起使用.当我将其更改为时,它可以工作
doSomeThingCleanUpLike (this->x);
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
抽象类和只有受保护构造函数的类之间有什么区别?它们似乎与我非常相似,因为你无法实例化任何一个.
编辑:
如何在派生类中创建实例,并使用带有受保护构造函数的基类?例如:
public class ProtectedConstructor
{
protected ProtectedConstructor()
{
}
public static ProtectedConstructor GetInstance()
{
return new ProtectedConstructor(); // this is fine
}
}
public class DerivedClass : ProtectedConstructor
{
public void createInstance()
{
ProtectedConstructor p = new ProtectedConstructor(); // doesn't compile
}
public static ProtectedConstructor getInstance()
{
return new ProtectedConstructor(); // doesn't compile
}
}
Run Code Online (Sandbox Code Playgroud) 我在学习Scala时遇到了困难.我有一个继承层次结构,基本上等同于:
class A {
protected def myMethod() = println("myMethod() from A")
}
class B extends A {
def invokeMyMethod(a: A) = a.myMethod()
}
Run Code Online (Sandbox Code Playgroud)
但是尝试编译这个示例,我得到错误"test.scala:7:error:方法myMethod无法在A中访问".
来自Java,我的理解是受保护的成员应该可以在派生类的任何位置访问,而且我在任何地方都看不到任何告诉我Scala中的受保护成员受实例限制的内容.有没有人对此有解释?
#include <iostream>
class A {
protected:
void foo()
{}
};
class B : public A {
public:
void bar()
{
std::cout << (&A::foo) << std::endl;
}
};
int main()
{
B b;
b.bar();
}
Run Code Online (Sandbox Code Playgroud)
这里我试图获取基类的受保护成员函数的地址.我收到了这个错误.
main.cpp: In member function ‘void B::bar()’:
main.cpp:5: error: ‘void A::foo()’ is protected
main.cpp:13: error: within this context
make: *** [all] Error 1
Run Code Online (Sandbox Code Playgroud)
将foo改为公共工程.还有印刷&B::foo作品.能否解释为什么我们无法获得基类的受保护成员函数的地址?
如果我有一个类我想要的方法protected和internal.我希望只有程序集中的派生类才能调用它.
由于protected internal手段protected 或者 internal,你必须做出选择.在这种情况下你选择什么 - protected或者internal?
假设您必须访问代码中某处的Java对象的受保护方法.你的解决方案是什么?
我知道一种方法:您可以使用反射并在Method对象上调用setAccessible(true).
还有其他想法吗?
在Java中声明变量时,"protected"和"no access modifier"之间有什么区别?它是一样的吗?
我有一个组件类,它定义了Component一般应该如何创建的静态模板方法:
class Component {
protected:
uint32_t id;
Component(uint32_t id) :
id(id) {
}
template<typename T, uint32_t C>
static T* createComponent() {
// content here not relevant
return new T(someParameter);
}
};
Run Code Online (Sandbox Code Playgroud)
然后有一个实现,例如a Button.不应该直接使用此类的构造函数,而是使用一个调用Component::createComponent模板函数的静态方法.
class Button: public Component {
protected:
Button(uint32_t id) :
Component(id) {
}
public:
static Button* create();
};
Run Code Online (Sandbox Code Playgroud)
实现看起来像这样,将类型传递给实例化,并在创建中使用常量:
Button* Button::create() {
return createComponent<Button, UI_COMPONENT_BUTTON>();
}
Run Code Online (Sandbox Code Playgroud)
现在的问题是,编译器抱怨"错误:'Button :: Button(uint32_t)'受到保护".根据我的理解,这个构造函数调用应该可以作为Button扩展Component,但这似乎是一个问题.
我怎么解决这个问题?
我现在陷入了一个奇怪的问题.我写了一个非常简化的版本.
class Base
{
public:
virtual int func1()=0;
virtual int func2()=0;
protected:
int n;
};
class der1: public Base
{
// implements the virtual functions of the base and uses the protected data
// members of the base.
};
class der2: public Base
{
// implements the virtual functions of the base and uses the protected data
// members of the base.
}
Run Code Online (Sandbox Code Playgroud)
现在的问题....都der1和der2实现基础的虚拟功能几乎相同的方式.但是其他一些类(der3,der4)也有自己的实现.但仍需要继承基地.我如何重构代码以oop方式删除代码重复?
[class.access/1] 中的 C++ 标准规定(强调我的):
一个类的成员可以是
- 私人的; 也就是说,它的名字只能被声明它的类的成员和朋友使用。
- 受保护;也就是说,它的名称只能由声明它的类的成员和朋友、从该类派生的类及其朋友使用(参见 [class.protected])。
- 民众; 也就是说,它的名字可以在任何地方使用而不受访问限制。
那么为什么编译器会在下面的 C++ 程序中引发这个错误呢?
#include <iostream>
class B {
protected:
static int const i = 1;
};
class D: public B {
public:
void f();
friend void g();
};
void D::f() {
B b;
std::cout << b.i; // OK
}
void g() {
B b;
std::cout << b.i; // error: 'i' is a protected member of 'B'
}
int main() {
D d;
d.f();
g();
return 0;
} …Run Code Online (Sandbox Code Playgroud)