【问题标题】:Why does Qt default signals to be public?为什么 Qt 默认信号是公开的?
【发布时间】:2019-09-13 02:52:49
【问题描述】:

我今天意识到,如果你有 3 个这样的课程:

第 1 类有信号

2 类有一个信号连接到 3 类的专用插槽

class 3 有一个私有 slot,class 2 是 class 3 的朋友

如果我将 1 类的信号连接到 2 类的信号,我基本上可以通过发出 1 类的信号来调用 3 类的私有插槽。

如果信号是私有的或受保护的,则不会发生这种情况。

还有另一种情况可能会很糟糕,假设我们有这样的设置:

第 1 类有信号

类 2 有一个信号连接到它的基类受保护的插槽

类 3 是具有受保护插槽的基类

这不违反面向对象的原则吗?

【问题讨论】:

  • 朋友类倾向于打破“面向对象的原则”
  • @Kevin 在第二种情况下有一个基类怎么样
  • 受保护的字段(槽、数据成员等)可以做同样的事情。 Class 2 可以做任何它想做的事情来保护它继承的东西。与信号/插槽相比,公共/受​​保护/私有接口更像是一个“问题”。我对 Qt 不熟悉,所以我无法回答那里做出的设计选择,但由于 C++ 是一种多范式语言,你可以在喜欢的时候打破 OOP。
  • 无论如何,您都不能使用 C++ 私有/公共机制来保护您的代码。你为什么想要?如果攻击者可以访问您的代码,他们无论如何都可以做任何事情。但是,请查看 PIMPL idiom,它被 Qt 库本身广泛用于隐藏 Private IMPlementation(在 Qt 的情况下,允许在库的次要版本之间保持二进制兼容性)。
  • 另外,如果你担心别人做你不想允许的事情,你可能想检查 Qt 元对象系统...它允许 QObject 类自省/反射,你可以调用任何可调用的方法(信号、槽和 Q_INVOKABLE 标记的方法)并访问属性并找出 QObject 父子层次结构树。

标签: c++ qt signals slots


【解决方案1】:

woboq 提到这一点:

信号在 Qt4 及之前的版本中受到保护。它们在 Qt5 中公开以启用the new syntax


您可以使用“私有”信号创建私有/受保护的辅助对象:

class Helper : public QObject
{
    Q_OBJECT
public:
    Helper(QObject *parent) : QObject(parent) { }
signals:
    void MyPrivateSignal();
};

class MyClass : public QObject
{
    Q_OBJECT
public:
    MyClass()
        : QObject(),
        helper(new Helper(this))
    {
        connect(helper, &Helper::MyPrivateSignal, this, &MyClass::MyPrivateSlot);
    }

private slots:
    void MyPrivateSlot();

private:
    void InvokeMyPrivateSignal()
    {
        emit helper->MyPrivateSignal();
    }

private: // or protected:
    Helper *helper;
};

任何人都可以连接到Helper 实例的Helper::MyPrivateSignal(),但不能连接到你的 Helper 实例,因为只有你知道那个。

【讨论】:

  • 谢谢,我会试试这个解决方案,看来它可以解决我想要阻止的问题。
猜你喜欢
  • 2014-01-03
  • 2011-01-19
  • 2014-03-04
  • 1970-01-01
  • 1970-01-01
  • 2011-09-10
  • 2011-01-09
  • 2019-04-25
  • 2010-11-24
相关资源
最近更新 更多