C++ 专项训练错题

1.

class CParent 
{
    public: virtual void Intro()
    {
        printf( "I'm a Parent, " ); Hobby();
    }
    virtual void Hobby()
    {
        printf( "I like football!" );
    }
}; 
class CChild : public CParent { 
    public: virtual void Intro()
    {
        printf( "I'm a Child, " ); Hobby();
    }
    virtual void Hobby()
    {
       printf( "I like basketball!\n" );
    }
}; 
int main( void )
{
    CChild *pChild = new CChild(); 
    CParent *pParent = (CParent *) pChild; 
    pParent->Intro(); 
    return(0);
}

 

解析:

上行转换 但是指针指向没变 然后调用子类重载 所以答案是 Im a Child I like footbal!

 

2.

 

解析: 类静态成员 在外面初始化 要指定是哪个类 及 Fred:: 同时省略static关键字

 

 

3.

class Test{
public:
    int a;
    int b;
    virtual void fun() {}
    Test(int temp1 = 0, int temp2 = 0)
    {
        a=temp1 ;
        b=temp2 ;
    }
    int getA()
    {
        return a;
    }
    int getB()
    {
        return b;
    }
};
 
int main()
{
    Test obj(5, 10);
    // Changing a and b
    int* pInt = (int*)&obj;
    *(pInt+0) = 100;  
    *(pInt+1) = 200;  
    cout << "a = " << obj.getA() << endl;
    cout << "b = " << obj.getB() << endl;
    return 0;
}
 
解析:有虚函数的类 在32位系统里 类起始地址前四个是虚函数指针 所以 *(pInt+0)=100是修改的虚函数表 所以答案为200,10

 

 

4.

链接:https://www.nowcoder.com/questionTerminal/ac7f182a41dd4c52b8895fcaf151e92d
来源:牛客网

class A  
{  
public:  
    A()  {     }  
    ~A() {    cout<<"~A"<<endl;   }  
};  
   
class B:public A  
{  
    public:  
        B(A &a):_a(a)  
        {  
             
        }  
        ~B()  
        {  
            cout<<"~B"<<endl;  
        }  
    private:  
        A _a;  
    };  
       
int main(void)  
 {  
        A a;       //很简单,定义a的时候调用了一次构造函数  
        B b(a); 
}
 
解析:
链接:https://www.nowcoder.com/questionTerminal/ac7f182a41dd4c52b8895fcaf151e92d
来源:牛客网

# include <iostream>
using namespace std;
class A  
{  
public:  
    A()  {  cout<<"create A"<<endl;   }  
    A(const A& other){ cout<<"copy A"<<endl;} //复制构造函数
    ~A() {    cout<<"~A"<<endl;   }  
}; 
class C
{
public:
    C()  {  cout<<"create C"<<endl;   } 
    C(const A& other){ cout<<"copy C"<<endl;} //复制构造函数
    ~C() {    cout<<"~C"<<endl;   }  
};
class B:public A  
{  
public:  
    B()
    {  
        cout<<"create B"<<endl;
    }  
    ~B()  
    {  
        cout<<"~B"<<endl;  
    }  
private:  
    C _a; 
};  
       
int main(void)  
{
        B b; 
        cout<<"------------------------"<<endl;
}
 
    
上面的输出结果为

create A
create C
create B
------------------------
~B
~C
~A

我们可以看到,这个地方先是调用parent class的构造函数,然后对成员变量C类型的构造函数,然后再最后执行B类型的构造函数。

析构的过程就是上面的过程反过来。

最开始析构b,~B,这个是没有争议的。
接着是析构b的成员变量_a,所以是~A
接着是b的parent class(基类)的~A
最后才是a的析构~A

不过为了理解这道题,我感觉配上我的例子更好理解一点,原题的成员变量和基类都是相同的类型,比较难以辨认。
 
于构造函数:基类构造函数 > 子类成员变量构造函数 > 子类构造函数
对于析构函数:子类析构函数 > 子类成员变量析构函数 > 基类析构函数
 
 
5.
class A
{
public:
    void f()
    {
        printf("A\n");
    }
};
 
class B: public A
{
public:
    virtual void f()
    {
        printf("B\n");
    }
};
 
int main()
{
    A *a = new B;
    a->f();
    delete a;
    return 0;
}
 
    

 

输出A

 

虽然是指向B 但是基类A没有virtual申明f函数 所以 a-->f()还是会调用基类的

 

6.

class A
{
public:
 void FuncA()
 {
     printf"FuncA called\n" );
 }
 virtual void FuncB()
 {
     printf"FuncB called\n" );
 }
};
class B : public A
{
public:
 void FuncA()
 {
     A::FuncA();
     printf"FuncAB called\n" );
 }
 virtual void FuncB()
 {
     printf"FuncBB called\n" );
 }
};
void main( void )
{
 B  b;
 A  *pa;
 pa = &b;
 A *pa2 = new A;
 pa->FuncA(); ( 3)
 pa->FuncB(); ( 4)
 pa2->FuncA(); ( 5)
 pa2->FuncB();
 delete pa2;
}
 
输出
FuncA called
FuncBB called
FuncA called
FuncB called

考点 就是父类指针指向子类实体对象 其实也就是关于虚函数重写的 写题没太看清楚
 
posted @ 2020-02-16 11:20  MengX  阅读(354)  评论(0编辑  收藏  举报

梦想不是空想