C ++ 11声明工厂是基类的朋友 [英] C++11 Declaring factory a friend of base class

查看:195
本文介绍了C ++ 11声明工厂是基类的朋友的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为派生类创建一个工厂。我只想让工厂能够创建派生类的实例,所以我已经使基本构造函数 protected ;派生类只使用基类构造函数,所以它们的构造函数也是 protected

I'm trying to create a factory for derived classes. I only want the factory to be able to create instances of the derived classes so I've made the base constructor protected; the derived classes just use the base class constructors so their constructors are protected also.

我试图声明工厂作为基类的一个朋友,以便它可以访问 protected 构造函数。当我使用此命令编译时

I tried to declare the factory as a friend of the base class so that it could access the protected constructor. When I compile using this command

clang++ -std=c++11 -stdlib=libc++ Friends.cpp -o Friends

我收到此错误:

Friends.cpp:23:20: error: calling a protected constructor of class 'A'
        return new T(i);
               ^
Friends.cpp:42:16: note: in instantiation of function template specialization 'Create<A>' requested
      here
        A* a = Create<A>(1);
           ^
Friends.cpp:30:25: note: declared protected here
             using Base::Base;
                    ^

导出类的类似错误 B

我从stackoverflow.com阅读其他问题的感觉,这是不可能在C + + 11,但我不知道为什么。有人可以解释为什么这将不工作,也许一个替代?

I get the feeling from reading other questions on stackoverflow.com, that this isn't possible in C++11, but I'm not sure why. Can someone explain why this won't work and perhaps an alternative?

示例代码

#include <iostream>

using namespace std;

// Forward declaration
template<class T> T* Create(int i);

class Base {
    public:
        template<class T>
        friend T* Create(int);
        virtual void say() = 0;

    protected:
        Base(int i): i(i) { }   // This won't compile
        int i;
};

// Factory for Base class
template<class T>
T* Create(int i){
    return new T(i);
}

class A: public Base {
    public:
        using Base::Base;
        void say() { cout << "I am A and have a value of " << i << endl; }
};

class B: public Base{
    public:
        using Base::Base;
        void say() { cout << "I am B and have a value of " << i << endl; }
};

int main(){
    cout << "I'm creating A." << endl;
    A* a = Create<A>(1);
    a->say();

    cout << "I'm creating B." << endl;
    B* b = Create<B>(2);
    b->say();

    return 0;
}


推荐答案

一个基类,它保留原始构造函数的访问,而不管你在导出类中使用 c>声明的位置。

When you inherit a constructor from a base class it retains the access of the original constructor, regardless of where you place the using declaration in the derived class.

来自§12.9/ 4 [class.inhctor]

From §12.9/4 [class.inhctor]


这样声明的构造函数具有相同的访问权限作为 X 中的相应构造函数。 ...

A constructor so declared has the same access as the corresponding constructor in X. ...

如果您明确地将构造函数添加到派生类而不是从继承它们, Base

You can fix the error if you explicitly add constructors to derived classes instead of inheriting them from Base.

A(int i) : Base(i) {}

B(int i) : Base(i) {}

现场演示

另一个解决方案,当然是让 Base 的构造函数 public 。你也可以使它的析构函数 protected ,但它不是必要的,因为该类不能被实例化由于纯虚拟成员函数。

Another solution, of course, is to make Base's constructor public. You could also make its destructor protected, but it's not necessary since the class cannot be instantiated anyway due to the pure virtual member function.

class Base {
    public:
        template<class T>
        friend T* Create(int);
        virtual void say() = 0;

        Base(int i): i(i) { }   // This won't compile
        int i;
    protected:
        ~Base() {}
};

现场演示

这篇关于C ++ 11声明工厂是基类的朋友的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆