4

Parallelのサブクラスであるクラスを作成しようとしているstd::threadため、クラスは で定義されParallel.hていますが、メインメソッドは同じプロジェクト (ビジュアルスタジオ) の別のファイルで定義されています。以下のようにメソッドmain.cppでインスタンスを作成して関数Parallelを実行するとコード セグメント: 私は C++ を初めて使用します。ここに "Parallel.h" があります。join()main()

#include<thread>
using namespace std;
namespace Para{
class Parallel:thread
{
public:

    static void run(){

    }
    Parallel(void)
    {
    }

    virtual ~Parallel(void)
    {
    }

    inline static void start(Parallel* p){
                // (*p).join();
    }

    virtual void Parallel::start(thread& t){

    }
    static void parallelize(Parallel& p1,Parallel& p2){

    }
    inline virtual Parallel* operator=(thread* t){
        return  static_cast<Parallel*>(t);
    }
}

//main.cpp 内

void main(){

    Parallel p;
    p.join();
    thread t(print);
     t.join();
     system("Pause");

}

問題は、関数名をパラメーターとして受け取るオーバーロードされたコンストラクターを持つスレッド クラスの適切なサブクラスを定義する方法です。またp.join()、VS2012 で次のエラーが発生したコンパイラーを定義する場合も同様です。

エラー 2 エラー C2247: 'Para::Parallel' は 'private' を使用して 'std::thread' C:\Users\Gamer\Desktop\PROJECQ\VC++@OMAQ を継承しているため、'std::thread::join' にアクセスできません\CQ47\CQ47\main.cpp 11

3 IntelliSense: 関数 "std::thread::join" ("H:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\thread" の 209 行目で宣言) にアクセスできません c:\Users\Gamer\デスクトップ\PROJECQ\VC++@OMAQ\CQ47\CQ47\main.cpp 11

4

2 に答える 2

6

「p.join()」を呼び出そうとしたときの「uses 'private' to inherit」に関するエラーは、次のように記述したためです。

    class Parallel:thread

あなたが書くべきだったとき:

    class Parallel : public thread

デフォルトはプライベート継承です。これは、基本クラスのすべてのメソッドが継承クラスでプライベートになることを意味します。継承にアクセスできるようにする場合は、継承を公開するように指定する必要があります。

于 2013-10-06T20:43:35.323 に答える
1

Java では関数は第一級市民ではないため、関数に関連するすべては、Swing の Observer パターンの実装のように、クラスと継承を介して実現されます。イベントのハンドラーのインターフェースを実装するクラスを作成します (関数を提供するためだけにクラス全体を実装します)。

スレッドでも同じことが起こります。関数をスレッドに渡すことができないため (Java には「関数」の概念がないため)、実行する独自の関数を実装するスレッド クラスから派生するか、またはそのクラスを渡す必要があります。実行するRunnable機能を提供するインターフェースを実装します(まさにそのObserver場合と同じです)。

C++ では、関数は (関数ポインター、ラムダ、ファンクターなどの形で) 第 1 級市民であるため、ここでのメカニズムは、実行する関数をスレッドに渡すことです。

オブジェクト指向のデザインの場合は、スレッドを継承するのではなく、構成 (実行のスレッドをクラスのメンバーとして格納) によってスレッドに適合させることを検討してください。

注: Java 8

補足として、Java 8 はラムダを実装し、それらを介して関数参照 (Hooray!) を提供します。しかし、Java関数ではファーストクラスの市民になることは決してないことが明らかになるため、インターフェースを使用してラムダを実装します。インターフェイスの問題は、ラムダの一般性を完全に破ることです。ラムダは、その署名に一致する任意のコンテキストで使用できます。Javaラムダではそうではありません。同じインターフェースを実装する必要があります。

于 2013-10-06T15:02:05.530 に答える