C++练习题

--- title: "C++练习题" date: 2023-06-18T14:05:25+08:00 tags: ["C++"] categories: [] draft: false toc: true --- ## 多态 ### 判断 - Q1: 虚函数可以是内联的? A1: 错误。内联是编译时刻决定的,虚函数是运行时刻动态决定的,所以虚函数不能是内联函数。虚函数前加上inline不会报错,但是会被忽略。 - Q2: 一个类内部,可以同时声明 `static void fun()` 和 `virutal void fun()` 两个函数? A2: 错误。虽然静态函数不存在this指针,但是还是不能声明同参的虚函数和静态函数。 - Q3: 基类的析构函数非虚,派生类的析构函数是虚函数。delete派生类指针(指向派生类对象)会调用基类析构函数? A3: 正确。 > 通过**派生类指针**,删除派生类对象时,无论父类析构函数是不是虚函数,都会调用基类析构函数。 > > 通过**基类指针**,删除派生类对象时,是否调用基类析构函数,取决于基类析构函数是否是virtual函数 ### 知识点 可以通过对象名主动调用析构函数,主动调用构造函数会出错。 如果类中声明了构造函数(无论是否有参数),编译器便不会再为之生成隐含的构造函数。 构造函数不能是虚函数,析构函数可以是虚函数。 ### 编程 #### 析构函数需要声明为virtual ```cpp #include using namespace std; int g_num = 0; class Base { public: Base() {} ~Base() { g_num += 1; } }; class Derived:public Base { public: Derived() {} ~Derived() { g_num += 2; } }; int main() { Base *p = new Derived(); delete p; cout << g_num << endl; return 0; } // 输出:1 ``` #### 动态绑定依赖于指针或者引用 ```cpp #include using namespace std; class Base { public: virtual void fun() {cout << "base" << endl;} }; class Derived:public Base { public: virtual void fun() { cout << "derived" << endl;} }; void func1(Base &obj) { obj.fun(); } void func2(Base obj) { obj.fun(); } int main() { Base *pBase = new Derived(); func1(*pBase); // derived func2(*pBase); // base return 0; } ``` #### operator可以定义为虚函数 ```cpp #include using namespace std; class Base { public: virtual void operator == (int val2) { cout << "base: " << val2 << endl; } }; class Derived:public Base { public: virtual void operator == (int val2) { cout << "derived: " << val2 << endl; } }; int main() { Base *pBase = new Derived(); Derived *pDerived = new Derived(); *pBase == 10; *pDerived == 20; } // derived: 10 // derived: 20 ``` #### 绝不重新定义继承而来的缺省参数 ```cpp #include using namespace std; class Base { public: virtual void fun(string str = "base123") { cout << str << endl; } }; class Derived:public Base { public: virtual void fun(string str = "derived") { cout << str << endl; } }; int main() { Base *pBase = new Derived(); pBase->fun(); // base123 } ``` #### 同名const函数属于有效重载 ```cpp #include using namespace std; class Base { public: void func1() {cout << "non-const\n";} void func1() const {cout << "const\n";} }; int main() { Base b1; b1.func1(); // non-const。非常量对象也可以调用const函数,此处优先调用non-const函数 const Base b2; b2.func1(); // const。常量对象只能调用const函数 } ``` #### virtual函数的const必须统一 ```cpp #include using namespace std; class Base { public: virtual void display() const { cout << "Base"; } }; class Derived:public Base { public: virtual void display() { cout << "Derived"; } }; int main() { Base *pBase = new Derived(); pBase->display(); // Base } ``` #### 派生类生成过程 > 派生类构造函数执行顺序: > > 1.调用基类构造函数,调用顺序按照它们**被继承时声明的顺序**(从左向右) > > 2.对派生类新增的成员对象初始化,调用顺序按照它们**在类中声明的顺序** > > 3.执行派生类的构造函数体中的内容。 ```cpp #include #include using namespace std; class A { public: A(string name) {cout << name << " ";} }; class Base { public: Base(string str) : a1(str) {} public: A a1; }; class Derived : public Base { public: Derived() : a4("a4"), Base("a1"), a2("a2") {} public: A a2; A a3 = A("a3"); A a4; }; int main() { Derived d; return 0; } // 输出:a1 a2 a3 a4 ``` ```cpp #include #include using namespace std; class Base { public: Base(int val) : a(val) {} protected: int a; }; class Derived : public Base { public: Derived(int val1, int val2) : c(val2), Base(val1), b(a + c) { cout << a << " " << b << " " << c << endl; // a==1, b的值不确定, c==10 } private: int b; int c; }; int main() { Derived d(1, 10); } ```
posted @   devin1024  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示