简体   繁体   English

一个类可以在同一个命名空间中有一个同名的成员吗?

[英]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:尽管a1a2都是指向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.

相关问题 类的成员是否可以与其类型(另一个类)命名相同的名称? - Can a member of a class be named the same name as its type (another class)? 为什么类不能为函数和数据成员具有相同的名称? - Why can't a class have same name for a function and a data member? 局部变量可以与名称空间具有相同的名称吗? - Can a local variable have the same name as a namespace? 如何使用班级中另一个命名空间的同名班级? - How can I use a class with the same name from another namespace in my class? 在名称空间中使用具有相同名称的类? - Using a class in a namespace with the same name? 当 class 成员参数具有相同名称时,如何定义构造函数? - How can I define constructor when the class member parameters have the same name? 为什么不能使用与成员类型同名的方法? - Why can't I have a method with the same name as a member type? 拥有与命名空间同名的变量是否正确 - Is it correct to have a variable with the same name as a namespace 有没有办法将类嵌入具有相同名称的新命名空间中? - Is there a way to embed a class in a new namespace with the same name? C ++将私有成员从派生类访问到另一个派生类(两者都具有相同的基类) - C++ Access private member from a derived class to another derived class (both have the same base class)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM