[英]Can a class have a member that is another with the same name in the same namespace?
Suppose I have two classes with the same name in the same namespace in two different files.假设我在两个不同文件的同一个命名空间中有两个同名的类。
This is so I can construct another object with each of the two classes, following the same interface but with some functions that behave differently.这样我就可以用这两个类中的每一个构造另一个对象,遵循相同的接口,但有一些行为不同的函数。
For the differently behaving functions, I will redefine them in one instance of the class.对于不同行为的函数,我将在类的一个实例中重新定义它们。
For the functions behaving the same way, I want to construct an instance of the other class and forward calls.对于行为相同的函数,我想构造另一个类的实例并转发调用。
Is there a way to do this?有没有办法做到这一点? Clearly I can't have two classes in the same namespace, but perhaps I can redefine the namespace/classname of the class I want to be a member in order to forward calls?
显然我不能在同一个命名空间中有两个类,但也许我可以重新定义我想成为成员的类的命名空间/类名以便转发调用?
For example:例如:
//file_1.h
namespace x {
class y {
}
}
//file_2.h
#include "file_1.h"
namespace x {
class y {
// member of same class in the other file
y memberName;
}
}
You can not modify a class after it has been declared and you can not declare two different classes with the same name.一个类在声明后不能修改,也不能声明两个不同的同名类。
You can declare a class hierarchy with virtual methods and use a pointer to the base.您可以使用虚拟方法声明类层次结构并使用指向基类的指针。 For example:
例如:
class A {
public:
virtual void f() = 0;
};
class B : public A {
void f() override {std::cout << "B" << std::endl;}
};
class C : public A {
void f() override {std::cout << "C" << std::endl;}
};
int main()
{
A *a1 = new B;
A *a2 = new C;
a1->f(); // B
a2->f(); // C
return 0;
}
Although both a1
, a2
are pointers to A
, the code will print:尽管
a1
和a2
都是指向A
指针,但代码将打印:
B
C
If you do not want to made this class hierarchy public, you can use the pimpl technique .如果不想公开此类层次结构,可以使用pimpl 技术。 It allows you to hide the real implementation of a class.
它允许您隐藏类的真实实现。 For example:
例如:
// File: A.h
class A {
class AImpl;
std::unique_ptr<AImpl> m_pimpl;
public:
explicit A();
void f();
};
// File A.cpp
class A::AImpl {
public:
void f() { std::cout << "A" << std::endl;};
};
A::A() : m_pimpl(new AImpl) {
}
void A::f() {
m_pimpl->f();
}
Now, you can define inside your cpp file the implementation of class AImpl.现在,您可以在 cpp 文件中定义类 AImpl 的实现。 You can even use a class hierarchy for
AImpl
to create different behaving objects depending on the class that you have created internally.您甚至可以使用
AImpl
的类层次结构根据您在内部创建的类来创建不同的行为对象。
Suppose I have two classes with the same name in the same namespace in two different files.
假设我在两个不同文件的同一个命名空间中有两个同名的类。
Then you have violated a rule called thd ODR or one definition rule.那么您违反了称为 thd ODR 的规则或一个定义规则。 Doing so makes your program ill-formed, no diagnostic required.
这样做会使您的程序格式错误,无需诊断。
If you have a class Alice
that wants tomuse another class Bob
, but you want two different definitions for how Bob
works, the solutions are called "polymorphism".如果您有一个类
Alice
想要使用另一个类Bob
,但您想要两种不同的Bob
工作方式定义,则该解决方案称为“多态性”。
Polymorphism is the ability for two or more classes to substitute for one.多态性是两个或多个类替代一个的能力。
There are three simple forms of polymorphism.存在三种简单形式的多态性。 There is using a virtual interface and runtime polymorphism.
有使用虚拟接口和运行时多态性。 There is using templates and compile time pokymorphism.
有使用模板和编译时pokymorphism。 Then there is type erasures via function pointers.
然后是通过函数指针进行类型擦除。
The easiest is defining a virtual interface.最简单的方法是定义一个虚拟接口。
struct IBob {
virtual int count() const = 0;
virtual ~IBob() {}
};
struct Alice {
std::unique_ptr<IBob> my_bob = nullptr;
void do_stuff() const {
if(my_bob) std::cout << "Count is:" << my_bob->count() <<"\n";
}
};
now we can define two implementations of IBob
:现在我们可以定义
IBob
两个实现:
struct Bob0:IBob{
int count() const final { return 7; }
};
struct Bob1:IBob{
std::unique_ptr<IBob> pBob;
int count() const final {
if(pBob) return pBob->count()*2 +1;
else return 1;
}
};
now Bob1
has a IBob
, and it uses that IBob
to implement its own count
.现在
Bob1
有一个IBob
,它使用该IBob
来实现自己的count
。
The template way looks like:模板方式如下所示:
template<class Bob>
struct Alice {
Bob my_bob;
void do_stuff() const {
std::cout << "Count is:" << my_bob.count() <<"\n";
}
};
and the various Bob
implementations need no virtual
or inheritance.并且各种
Bob
实现不需要virtual
或继承。 Here you must pick which Bob
at compile time at each point of use.在这里,您必须在每个使用点的编译时选择哪个
Bob
。
The manual function pointer type erasure solution is more complex.手动函数指针类型擦除解决方案更复杂。 I'd advise against it.
我建议不要这样做。
When you include a file is like adding the content to that cpp file.包含文件就像将内容添加到该 cpp 文件中。 So that means you will have the same name for different classes.
因此,这意味着您将对不同的类使用相同的名称。
There is a possibility to use the same name by using typedef.有可能通过使用 typedef 来使用相同的名称。
class A {
public:
static void func() {}
};
class B {
public:
static void func() {}
};
void funcA() {
typedef A C;
C::func();
}
void funcB() {
typedef B C;
C::func();
}
int main()
{
funcA();
funcB();
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.