限制对C ++构造函数和析构函数的访问 [英] Restricting Access to C++ Constructor and Destructor

查看:75
本文介绍了限制对C ++构造函数和析构函数的访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请原谅我是否已被问到,我没有找到具体问题的答案.

Forgive me if this has already been asked, I didn't find any answers to my specific question.

我在一个正在制作的库中有一个类,我希望某些类能够创建和销毁,而其他类则能够访问其他公共功能.拥有 friend class 也不是我想要的,因为friend class可以访问不需要的成员变量和成员函数.我偶然发现了这个习惯用法,它几乎可以正常工作,但析构函数除外,因为它不能采用其他参数.有了这个成语,我得到了:

I have a class in a library I'm making that I want certain classes to be able to create and destroy, and other classes to be able to access other public functions. Having a friend class is not what I want either as the friend class will get access to member variables and member functions which I don't want. I stumbled upon this idiom which almost works, except for the destructor since it can't take additional parameters. With that idiom, I get:

class B;
class A
{
    public:
        class LifecycleKey
        {
            private:
                LifecycleKey() {}
                friend class B;
        };

        A(LifecycleKey); // Now only class B can call this
        // Other public functions

    private:
        ~A(); // But how can I get class B to have access to this?

        void somePrivateFunction();

        // Members and other private functions
};

以上代码中提到,该解决方案不允许仅 B类访问析构函数.

As alluded to in the above code, the solution doesn't allow only class B to have access to the destructor.

尽管上述所有问题都不是破坏交易的因素,因为我总是可以将ctor和dtor公开,并且只说"RTFM".

While none of the above issues are deal breakers by any stretch as I can always just make ctor and dtor public and just say "RTFM".

我的问题是:

是否有某种方法可以将对ctor和dtor的访问限制为特定的类(但仅限于ctor和dtor),同时遵循更广为人知的语法(如果需要,可以将某些东西放在堆栈中,通过delete销毁等).)?

Is there is some way to limit access to ctor and dtor to specific classes (but only the ctor and dtor) while adhering to more well known syntax (having stuff be on the stack if people want, destroying via delete , etc.)?

任何帮助将不胜感激!

解决方案

A.h

class B;
class A
{
    protected:
        A() {}
        virtual ~A() {}
        A(const A&); // Implement if needed
        A(A&&); // Implement if needed

    public:
        // Public functions

    private:
        void somePrivateFunction();

        // Members and other private functions
};

B.h

class B
{
    public:
        B();
        ~B();
        const A* getA() const;

    private:
        A* m_a;
}

B.cpp

namespace {
    class DeletableA : public A {
        public:
            DeletableA() : A() {}
            DeletableA(const DeletableA&); // Implement if needed
            DeletableA(DeletableA&&); // Implement if needed
            ~DeletableA() {}
    }
}

#include B.h
B::B() : m_a(new DeletableA()) {}
B::~B() { delete static_cast<DeletableA*>(m_a); }
const A* B::getA() const { return m_a; }

或者,如果在 Bh Ah 中需要 DeletableA 类(由于内联,模板化或希望拥有所有 A类中的相关类( Ah ),可以使用构造函数上的"pass key"将其移到那里,因此没有其他类可以创建一个.即使析构函数将被公开,其他任何类也无法删除 DeletableA .

Alternatively, if the DeletableA class is needed in B.h or A.h (due to inlining, templating, or desire to have all class A related classes in A.h), it can be moved there with a "pass key" on the constructor so no other classes can create one. Even though the destructor will be exposed, no other class will ever get a DeletableA to delete.

很明显,此解决方案要求 B类知道要创建 Deletable A 的实例(或者如果未在 Ah中公开该类,则要使其成为一般类)),并且仅存储通过公共功能公开的 A * ,但这是建议的最灵活的设置.

Obviously this solution requires that class B know to make instances of Deletable A (or to make the class in general if it isn't exposed in A.h) and only store A* that are exposed via public functions, but, it is the most flexible set up that was suggested.

尽管其他某些类仍然可以成为 A类的子类(因为 A类不是"final"),但是您可以添加另一个"pass key"",以防止这种行为.

While still possible for some other class to make a subclass of class A (since class A isn't "final"), you can add another "pass key" to the constructor of A to prevent such behavior if you wish.

推荐答案

出于这个目标,类 B 应该是唯一能够实例化和销毁类 A :

For the goal that class B should be the only one able to instantiate and destroy objects of class A:

  • 对于静态和自动变量,只需要限制对构造函数的访问,并且您已经在这样做了.

  • For static and automatic variable, restricting access to the constructor is all that's needed, and you're already doing that.

对于动态分配的对象,您可以限制对其释放函数, operator delete operator delete [] 的访问,并让析构函数公开.这禁止除 B 之外的其他代码删除对象.

For dynamically allocated object you can restrict access to its deallocation functions, operator delete, and operator delete[], and leave the destructor public. This prohibits other code than B from deleting objects.

对于动态对象,您可以从受 protected 虚拟析构函数或具名 B 作为朋友.然后, B 可以通过强制转换为它可以访问的接口来销毁任何动态 A 对象.

For dynamically objects you can derive class A from an interface with protected virtual destructor or named self-destroy function, which has class B as friend. B can then destroy any dynamic A object by casting up to the interface that it has access to.

显式调用析构函数的代码应得到其应得的一切.

Code that explicitly calls the destructor deserves whatever it gets.

请记住,您永远不会为恶意代码建立坚不可摧的防御措施,只是为无意中错误使用建立合理的检测和编译时间报告.

Remember, you're never building an impregnable defense against malicious code, you're just building a reasonable detection and compile time reporting of inadvertent incorrect use.

这篇关于限制对C ++构造函数和析构函数的访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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