C ++在未准备好时调用getter方法

时间:2016-12-07 16:27:13

标签: c++

我正在研究一个项目并且它有效,但它确实很混乱,所以我试图通过移动来清理它。

这是包含getter方法的类的简短版本

Link::Link
{
    jsonUrl = QUrl("www.example.json");
    QNetworkAccessManager *nam = new QNetworkAccessManager(this);
    connect(nam,SIGNAL(finished(QNetworkReply*)),this,SLOT(downloadFinished(QNetworkReply*)));
    QNetworkRequest request(jsonUrl);
    nam->get(request)
}
void Link::downloadFinished(QNetworkReply *reply)
{
    jsonArray = reply->readAll();
    jsonStuff();
}
void Link::jsonStuff()
{
    //does a bunch of json stuff then gets a string
    string = map["url"].toString();    
}
QString Link::getString()
{   
    return string;
}

这是在构造函数

中调用getter的类的简短版本

标题

class Commands
{
private:
    Link link; 
}

构造函数内的源代码

Commands::Commands()
{
    addCommand("!test", link.getString()); 
}

问题是,当我尝试这样做时,我认为Commands构造函数首先运行,而Link类中的字符串尚未就绪,因此link.getString()出来的字符串为空。有没有办法等到Link类完成它的操作并在命令构造函数中调用link.getString()之前填充字符串?不确定这是否重要,但我的大部分代码都是用Qt编写的

我希望你们能理解我想问的问题。我的术语真的很差。

编辑:为我的链接类添加了更多内容

2 个答案:

答案 0 :(得分:2)

当首先调用Commands的构造函数(在本例中为Commands())时,它会在Commands类中创建所有变量(它们是未初始化的)。即所谓的链接是通过Link()创建的。你可能想要做的是在Link()构造函数中使用jsonStuff()(它创建所有成员变量),注意它创建变量,在这种情况下,它创建带有基本结构的字符串 - 它创建空字符串。)请尝试以下填写字符串:

 Link() {
    jsonStuff(); // string will be set
 }

或者你可以通过初始化部分初始化它:

Link() : string("Text") { }

此外,您可能希望从getString()函数返回对字符串的引用。引用意味着它不会创建额外的副本并返回存储在Link中的字符串,因此您可以在调用getString()的函数中更改字符串。此外,如果它是只读的,你应该使用const引用。

答案 1 :(得分:0)

  

有没有办法等到Link类完成它之后填充字符串并在link.getString()的构造函数中调用Commands之前填充字符串?

当然可以。 Link类必须是QObject,它在更改其属性时会发出信号 - 可能是基于它对网络请求的回复。

class Link : public QObject {
  Q_OBJECT
  Q_PROPERTY(QString string READ string WRITE setString NOTIFY stringChanged)
  QString m_string;
public:
  void jsonStuff() {
    ...
    connect(reply, &QNetworkReply::finished, this, [this]{
      ...
      setString(map["url"].toString());
    });
  }
  void setString(const QString &s) {
    if (m_string == s) return;
    m_string = s;
    emit stringChanged(m_string);
  }
  QString string() const { return m_string; }
  Q_SIGNAL void stringChanged(const QString &);
};

然后,您可以在链接准备就绪时添加命令:

Commands::Commands()
{
  connect(&link, &Link::stringChanged, this, [this](const QString &string){
    if (!string.isEmpty()) addCommand("!test", string);
  });
}