2

基本的なC++の使用法について、ScottMeyerによる構築または破棄中に仮想関数を呼び出さないでくださいを読んでいました。

g ++には、本当に効果的なこの悪いコーディングについて警告するコンパイラフラグがあるかどうか疑問に思いました。そうでない場合、このチェックを行うためのコーディング方法は何でしょうか?

このような種類のチェックをコーディングする場合は、スタックを使用し、各呼び出しで情報を挿入することでこのジョブにアプローチします(呼び出しスタックを実装する方法)。

私がまだ必要としているのは、関数が仮想であるかどうか、または関数がコンストラクターであるかどうかをテストする方法です。とにかく、あなたが知っていることを行う方法はありますか?.NETの「リフレクション」のアイデアに似たものはありますか?

4

2 に答える 2

2
> cat nevercall.cpp             
class Transaction {
public:
    Transaction();
    virtual void logTransaction() const = 0;

    // ...
};

Transaction::Transaction()
{
    //...
    logTransaction();
}

class BuyTransaction: public Transaction {
public:
    virtual void logTransaction() const;

    //...
};

class SellTransaction: public Transaction {
public:
    virtual void logTransaction() const;

    // ...
};

int main()
{
    BuyTransaction b;
}

Meyerのサンプルコードにあるように、usingは、純粋-Weffc++である場合(およびその場合のみ)にこれについて警告します。virtual void Transaction::logTransaction() const

> g++ -Weffc++ nevercall.cpp -o nevercall
nevercall.cpp:1:7: warning: 'class Transaction' has virtual functions and accessible non-virtual destructor [-Wnon-virtual-dtor]
nevercall.cpp: In constructor 'Transaction::Transaction()':
nevercall.cpp:12:20: warning: pure virtual 'virtual void Transaction::logTransaction() const' called from constructor [enabled by default]
nevercall.cpp: At global scope:
nevercall.cpp:15:7: warning: 'class BuyTransaction' has virtual functions and accessible non-virtual destructor [-Wnon-virtual-dtor]
nevercall.cpp:22:7: warning: 'class SellTransaction' has virtual functions and accessible non-virtual destructor [-Wnon-virtual-dtor]
于 2012-05-28T11:21:21.233 に答える
2

PC-Lintがやってくれます!

私はこのテストプログラムでそれを実行しました:

#include <stdio.h>

class Base
{
public:
        Base() { moo(); }
        virtual ~Base() { ; }
        virtual void moo(void) { printf("Base::moo\n"); }
};

class Derived : public Base
{
public:
        Derived() { ; }
        virtual void moo(void) { printf("Derived::moo\n"); }
};

int main(void)
{
        Derived j; // Outputs 'Base::moo'
}

そしてそれは不平を言った:

警告1506:コンストラクタまたはデストラクタ内の仮想関数'Base :: moo(void)'の呼び出し

于 2012-05-28T23:32:21.117 に答える