24

私はちょうど問題に遭遇します

error: request for member ‘show’ in ‘myWindow’, which is of non-class type ‘MainGUIWindow()’

単純なqtアプリケーションをコンパイルしようとすると:

#include <QApplication>
#include "gui/MainGUIWindow.h"


int main( int argc, char** argv )
{
  QApplication app( argc, argv );


  MainGUIWindow myWindow();
  myWindow.show();


  return app.exec();
}

私はこれを置き換えることで解決しました

MainGUIWindow myWindow(); 

MainGUIWindow myWindow;

でも違いがわかりません。私の質問:違いは何ですか?

よろしく、ダーク

4

7 に答える 7

49

他の回答は、括弧のバージョンが実際には関数宣言であると正しく述べています。直感的に理解するためにMainGUIWindow f();、「関数のように見える」と書いたとしましょう。:)もっと興味深い質問は、の違いは何ですか

MainGUIWindow* p = new MainGUIWindow;

MainGUIWindow* p = new MainGUIWindow();

括弧のあるバージョンは値の初期化と呼ばれ、括弧のないバージョンはデフォルトの初期化と呼ばれます。非PODクラスの場合、2つの間に違いはありません。ただし、POD構造体の場合、値の初期化には、すべてのメンバーを0に設定することが含まれます。

my2c

追加:一般に、構文構造が宣言と他の何かの両方として解釈できる場合、コンパイラーは常に宣言を優先してあいまいさを解決します。

于 2011-02-25T11:23:38.880 に答える
19

以下:

MainGUIWindow myWindow();

引数を取らずにを返す関数を宣言しますMainGUIWindow。つまりmyWindow、関数名です。

MainGUIWindow myWindow;

一方myWindow、タイプのオブジェクトを作成しますMainGUIWindow

于 2011-02-25T11:19:20.520 に答える
4

違いは、

MainGUIWindow myWindow(); 

関数を宣言しますmyWindow。これはパラメータを受け取らず、を返しますがMainGUIWindow

MainGUIWindow myWindow; 

タイプの新しいオブジェクトを作成しMainGUIWindow、それをデフォルトのコンストラクターと呼びます。

于 2011-02-25T11:20:07.107 に答える
4

あなたが説明した状況に実際の問題はありません。かっことビンゴを外します!できます。

「最も厄介な解析」は、単一のパラメーターを取り、一時的なものを渡したい場合、はるかに大きな問題です。

class Foo
{
public:
 explicit Foo( const Bar& bar );
};

Foo foo( Bar() );

Fooのインスタンスを作成しませんが、関数ポインターを受け取る関数も宣言します。これは実際にしばしばあなたを刺します。

于 2011-02-25T11:52:19.013 に答える
3

コードのあいまいさを解決するためのC++コンパイラのガイドラインの1つは、次のとおりです。何かが関数宣言になる可能性がある場合、それは関数宣言です。したがって、コンパイラが次のことを確認すると、次のようになります。

MainGUIWindow myWindow();

myWindowこれは、パラメーターを受け取らずにを返す、と呼ばれる関数を宣言していることを理解していますMainGUIWindow。明らかに、これはあなたが望むものではありません。

かっこを削除するだけで問題ありません。

MainGUIWindow myWindow; // Create an object called myWindow, of type MainGUIWindow
于 2011-02-25T11:21:11.153 に答える
0

C ++では、関数宣言のように見えるすべての式は関数の宣言です。あなたの質問のより複雑なサンプルを考えてみましょう:

#include <iostream>

struct X
{
  X( int value ) : x(value) {}
  int x;
};

struct Y
{
  Y( const X& x ) : y(x.x) {}
  int y;
};

int main()
{
  int test = 10;
  Y var( X(test) );                 // 1
  std::cout << var.y << std::endl;  // 2

  return 0;
}

一見したところ(1)はvar、型の一時変数で初期化する必要があるローカル変数の宣言ですX。しかし、これはコンパイラの関数宣言のように見え、(2)でエラーが発生します。

 error: request for member ‘y’ in ‘var’, which is of non-class type ‘Y(X)’

コンパイラーは、(1)が次の名前の関数であると見なしますvar

Y                var(             X                     test            );
^- return value  ^-function name  ^-type of an argument ^-argument name

では、関数を宣言したくないとコンパイラーに言うにはどうすればよいでしょうか。次のように追加の括弧を使用できます。

Y var( (X(test)) );  

コンパイラの場合MainGUIWindow myWindow()、関数宣言のようになります。

MainGUIWindow    myWindow(        void                  )
^- return value  ^-function name  ^-type of an argument
于 2011-02-28T20:53:29.597 に答える
-1

また、CppCon 2017から:LouisBrandy「Facebookで不思議なことに繰り返し発生するC++のバグ」</p>

std::unique_lock<std::mutex> (_mutex);

何もロックしない「_mutex」という名前のロックの宣言です。通常、後でロックを操作する必要がないため、名前を付けるのを見逃しがちです。

これは、デフォルトのコンストラクターと1つの引数を取るより便利なコンストラクターの両方を持つRAIIオブジェクトの問題です。

于 2020-08-06T22:15:31.697 に答える