zoukankan      html  css  js  c++  java
  • 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! " );
        }
    }; 
    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 ");
        }
    };
     
    class B: public A
    {
    public:
        virtual void f()
        {
            printf("B ");
        }
    };
     
    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 " );
     }
     virtual void FuncB()
     {
         printf"FuncB called " );
     }
    };
    class B : public A
    {
    public:
     void FuncA()
     {
         A::FuncA();
         printf"FuncAB called " );
     }
     virtual void FuncB()
     {
         printf"FuncBB called " );
     }
    };
    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

    考点 就是父类指针指向子类实体对象 其实也就是关于虚函数重写的 写题没太看清楚
     
  • 相关阅读:
    省市区distpicker,从数据库里查出来回显,动态绑定
    ajax请求里面的success和error里面的layer.msg,status: "parsererror",刷新父界面,碰到的一些问题
    排序算法时间和空间算法度
    适配器模式
    守护线程
    工厂模式之简单工厂模式、工厂模式、抽象工厂
    ArrayList源码分析和缩减版手写ArrayList(jdk1.8和1.9)
    HashMap排序题
    二进制中1的个数
    anaconda指定镜像源,解决conda下载速度慢失败问题
  • 原文地址:https://www.cnblogs.com/MengX/p/12316077.html
Copyright © 2011-2022 走看看