0

C++ でのクラス キャストに問題があります。
学ぶために、合計などの演算を行うクラスを作成したかったのですが、起動するたびにクラッシュするようです。

ここに私の簡単なクラスがあります:

#include <iostream>


class CCalculation {
public:
CCalculation() {};
virtual int calculate() = 0;
};


class CCalc_CONST : public CCalculation {
    int x;
public:
    CCalc_CONST(int a) : x(a) {};
    int calculate() { return x; };
};    


class CCalc_ADD : public CCalculation {
    CCalculation *x;
    CCalculation *y;
public:
    CCalc_ADD(CCalculation *a, CCalculation *b) {
        this->x = a;
        this->y = b;
    };
    int calculate() {
        std::cout << "Calculation...\n";
        return x->calculate() + y->calculate();
    };
};

そして私のテスト:

    CCalculation *a = &CCalc_CONST(4);
    CCalculation *b = &CCalc_CONST(1);
    CCalculation *c = &CCalc_ADD(a,b);

    std::cout << "res: " << c->calculate() << "\n";

毎回クラッシュするようです (コンパイラ エラーや警告は表示されませんでした)。私が見つけた唯一の実行方法は、CCalc_ADD 構築で a->calculate と b->calculate を出力しているときです。関数を機能させるために計算関数を呼び出す必要がある理由がまったくわかりません。

誰かが実際にそれを行う方法を私に説明してもらえますか?

4

4 に答える 4

3

まず、すべての警告をオンにする必要があります (コンパイラのドキュメントを参照してください gcc -Wall) 。

次に、コンパイラがあなたを非難することがわかります。

1.cpp: In function 'int main()':
1.cpp:56:37: error: taking address of temporary [-fpermissive]
1.cpp:57:37: error: taking address of temporary [-fpermissive]
1.cpp:58:37: error: taking address of temporary [-fpermissive]

実は、ここ

CCalculation *a = &CCalc_CONST(4);

作成後すぐに破棄される一時オブジェクトを作成するだけで、ポインターが壊れます。

2 つの選択肢があります。

  1. 動的メモリにオブジェクトを作成します (ただし、この場合、複雑な計算の所有者をより単純にすることをお勧めします)

    class CCalc_ADD : public CCalculation {
        std::unique_ptr<CCalculation> x;
        std::unique_ptr<CCalculation> y;
    public:
        CCalc_ADD(CCalculation *a, CCalculation *b):x(a), y(b)
        {
        };
        int calculate() {
            std::cout << "Calculation...\n";
            return x->calculate() + y->calculate();
        };
    };
    
    
    std::unique_ptr<CCalculation> a(new CCalc_CONST(4));
    //... 
    CCalc_ADD c (std::move(a), std::move(b));
    
  2. ポインタを参照に置き換えます。次に、値のセマンティクスを使用できます。

于 2012-08-20T18:42:33.110 に答える
2

使用する必要さえない作業プログラムを取得するには、次のようにしますnew

CCalc_CONST a(4);
CCalc_CONST b(1);
CCalc_ADD   c(&a,&b);

std::cout << "res: " << c.calculate() << "\n";
于 2012-08-20T18:55:05.873 に答える
0

もう生きていない一時オブジェクトにアクセスしようとしています。newオブジェクトにメモリを割り当て、そのコンストラクターを呼び出すには、演算子を使用します。

CCalculation *a = new CCalc_CONST(4);
CCalculation *b = new CCalc_CONST(1);
CCalculation *c = new CCalc_ADD(a,b);

GCCで試してみましたが、これについて非常に明確な警告が表示されます:

test.cpp: In function ‘int main()’:
test.cpp:35:33: error: taking address of temporary [-fpermissive]
test.cpp:36:37: error: taking address of temporary [-fpermissive]
test.cpp:37:37: error: taking address of temporary [-fpermissive]
于 2012-08-20T18:31:51.997 に答える