【问题标题】:Namespace-like access in class类中类似命名空间的访问
【发布时间】:2013-08-27 12:27:42
【问题描述】:

对于一个容器类,我想提供一个接口,其中包含几个分组分类的函数,例如:

Data::Get::FirstGetter()   
Data::Get::SecondGetter()  
Data::Set::FirstSetter()  
Data::Set::FirstSetter()  

这将允许这样的事情:

Data myData;
myData::Set::FirstSetter( stuff );
std::cout << myData::Get::FirstGetter() << std::endl; // -> "stuff"  

显然代码本身是伪造的,我使用范围运算符:: 作为其他东西的潜在占位符(我知道您不能在类中创建命名空间)。

在下面的 sn-p 中演示了一种实现类似功能的方法:

#include <iostream>

struct Foo {
private:
    struct aBar {
        void IFunc(){
            std::cout << "IFunc()" << std::endl;
        }
    };
public:
    void OFunc(){
    std::cout << "OFunc()" << std::endl;
    }
    aBar Bar;
};

int main(){
    Foo foo;
    foo.OFunc();
    foo.Bar.IFunc();
}

但是,为了使用它,必须为每个分组对象创建一个实例(在伪代码示例中,Get 的一个实例和Set 的另一个实例,在虚拟示例中aBar 的一个实例)。有没有办法以不同的方式实现此功能(可能使用实际的范围运算符:: 来指示要调用的成员位于内部范围内)?

【问题讨论】:

  • 这是可能的,但是你为什么要这样做而不是仅仅使用直接的方法呢?
  • 静态函数/成员
  • 听起来你是想绕过“普通”会员?或者,与Data.m_get.firstGetter() / Data.m_get.secondGetter()(其中m_get 是某个成员类)相比,您要实现的实际用例是什么?
  • 是的,当然,可以使用Get/Set 成员类来做同样的事情(如上所示)。我只是想问是否有另一种方法可以实现这一点,它确实可以绕过创建 Get/Set 内部类的实例。
  • 我认为你应该重新考虑你的设计。没有优雅的方法可以实现您想要的。

标签: c++ class namespaces


【解决方案1】:

我真的不明白你想要实现这种行为的原因。但是,如果您想实现类似的目标,您可能会受到以下启发(尽管我不会在任何项目中使用这样的代码,但仍然看不到一个合理的理由):

#include <iostream>

class Interface1
{
protected:
  virtual ~Interface1() {}
  virtual void DoStuff1() = 0;
};

class Interface2
{
protected:
  virtual ~Interface2() {}
  virtual void DoStuff2() = 0;
};

class Interface3
{
protected:
  virtual ~Interface3() {}
  virtual void DoStuff3() = 0;
};

class Container;

class Grouper1
{
public:
  static void DoStuff1(Container& arContainer);
  static void DoStuff2(Container& arContainer);
};

class Grouper2
{
public:
  static void DoStuff3(Container& arContainer);
};

class Container : public Interface1, public Interface2, public Interface3
{
public:
  virtual ~Container() {}
private:
  friend class Grouper1;
  friend class Grouper2;
  virtual void DoStuff1() { printf("DoStuff1()\n"); }
  virtual void DoStuff2() { printf("DoStuff2()\n"); }
  virtual void DoStuff3() { printf("DoStuff3()\n"); }
};

void Grouper1::DoStuff1(Container& arContainer) { arContainer.DoStuff1(); }
void Grouper1::DoStuff2(Container& arContainer) { arContainer.DoStuff2(); }

void Grouper2::DoStuff3(Container& arContainer) { arContainer.DoStuff3(); }

int main(int aArgc, char** aArgv)
{
  Container c;
  Grouper1::DoStuff1(c);
  Grouper1::DoStuff2(c);
  Grouper2::DoStuff3(c);
  return 0;
}

这样,您的 Container 可以实现一些接口,并且您的 Groupers 提供静态函数(分组)来访问这些方法(尽管您需要传递实际的 Container,但您想继续工作)。但如果不提供一些辅助函数/类(如 Grouper1、Grouper2),肯定不会实现类似命名空间的访问。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多