1

子クラス B を持つクラス A があり、A と B の仮想関数を呼び出すテンプレート関数を作成したいと考えています。

#include <stdio.h>
class A{
public:
    virtual void test(){
        printf("A\n");
    }
};
class B:public A{
public:
    virtual void test(){
        printf("B\n");
    }
};

template<class T>
void f(T t){
    t.test();
}
int main(){
    A* a=new B();
    f<A>(*a);
    return 0;
};

A のみを出力し、test() をオーバーライドしないようですが、変更すると

void f(T t) 

void f(T& t) 

そのように:

#include <stdio.h>
class A{
public:
    virtual void test(){
        printf("A\n");
    }
};
class B:public A{
public:
    virtual void test(){
        printf("B\n");
    }
};

template<class T>
void f(T& t){
    t.test();
}
int main(){
    A* a=new B();
    f<A>(*a);
    return 0;
};

、それはBを出力します、なぜそれが起こるのでしょうか?

4

4 に答える 4

0

を呼び出すとf(T t)、c++ は実際にはコンストラクターによって T のオブジェクトを新規作成しT(T& t)ます。次に、このオブジェクトの参照が関数に渡されます。

あなたはそれを証明するために書き込みコードを呼び出します

class A {
public:
    int x;
    A():x(6){
    }
    A(A& a) {
        x = 2;
    }
    virtual void test() {
        printf("%d\n", x);
    }
};
class B : public A {
public:
    virtual void test() {
        printf("%d\n", x);
    }
};

void fun(A a)
{
    a.test();
}

void f(A& a)
{
    a.test();
}
int main(void)
{
    A* a = new A();
    A* b = new B();
    A* c = new A(*b);
    fun(*a);
    fun(*b);
    f(*a);
    f(*b);
    f(*c);
}

出力は 2 2 6 6 2 です

于 2015-11-06T04:58:44.903 に答える