banner
cells

cells

为美好的世界献上 code

quiz

Q027#

#include <iostream>

struct A {
    virtual std::ostream &put(std::ostream &o) const {
        return o << 'A';
    }
};

struct B : A {
    virtual std::ostream &put(std::ostream &o) const override {
        return o << 'B';
    }
};

std::ostream &operator<<(std::ostream &o, const A &a) {
    return a.put(o);
}

int main() {
    B b;
    std::cout << b;
}

Answer

click to see answer B

Q029#

#include <iostream>

struct A {
    A() {
        // std::cout << "A::A()" << std::endl;
        foo();
    }
    virtual ~A() {
        // std::cout << "A::~A()" << std::endl;
        foo();
    }
    virtual void foo() {
        // std::cout << "A::foo()" << std::endl;
        std::cout << "1";
    }
    void bar() {
        // std::cout << "A::bar()" << std::endl;
        foo();
    }
};

struct B : public A {
    virtual void foo() {
        // std::cout << "B::foo()" << std::endl;
        std::cout << "2";
    }
};

int main() {
    B b;
    b.bar();
}

Answer

click to see answer 121

Explain

即使 A::foo() 是虚函数,但在构造和析构的过程中不会被认为是虚拟的。

在构造 B 之前应该构造 A,而在构造 A 的期间,B 尚未构造,所以不应该被使用,A::A() 中的 foo() 调用的自然是 A::foo()

在对象 b 销毁时,也面临同样的问题,因为先调用 B 的析构,然后再调用 A 的析构,在对象 b 析构后,B::foo() 也是不应该被使用的。

Q114#

#include <iostream>
#include <memory>
#include <vector>

class C {
public:
    void foo() {
        std::cout << "A";
    }
    void foo() const {
        std::cout << "B";
    }
};

struct S {
    std::vector<C> v;
    std::unique_ptr<C> u;
    C *const p1;
    C const *p2;

    S() : v(1)
        , u(new C())
        , p1(u.get()
        , p2(u.get()) {

    }
};

int main() {
    S s;
    s.v[0].foo();
    s.u->foo();
    s.p1->foo();
    s.p2->foo();

    const S &r = s;
    r.v[0].foo();
    r.u->foo();
    r.p1->foo();
    r.p2->foo();
}

Answer

click to see answer AAABBAAB

Explain

C *const p1 中 const 修饰 p1 指针,所以 s 对象的成员变量 p1 调用 foo 时会使用非 const 版本,C const *p2const 修饰 *p(C 类)对象,所以 s 对象的成员变量 p2 调用 foo 时会使用会使用 const 版本。

r 是对象 s 的常量引用,const 改变了成员 v 的行为,因为 std::vectoroperator[] 进行了重载,常量对象调用是返回常量引用的版本,返回的也是常量引用,因此调用 fooconst 版本。

Q360#

// using C++17
#include <iostream>
#include <type_traits>

int main() {
    std::cout << std::is_const_v<const int *>;
    std::cout << std::is_const_v<int *const>;

    std::cout << std::is_const_v<const int[1]>;
    std::cout << std::is_const_v<const int **>;
    std::cout << std::is_const_v<int *const *>;

    std::cout << std::is_const_v<const int(*)[1]>;
    std::cout << std::is_const_v<const int *[1]>;
    std::cout << std::is_const_v<const int[1][1]>;
}

Answer

click to see answer 0110001

Explain

const int * 是一个指向常量整数的指针,即常量指针,虽然指针指向的内容是常量,但是指针本身不是常量,所以结果为 false

int *const 是一个指针常量,指针本身是常量,所以结果为 true

const int[1] 是一个包含常量整数的数组,数组的元素是常量,所以结果为 true

const int ** 是一个指向 指向常量指针 的指针((const int *) *ptr),指针本身不是常量,所以结果为 false

int *const * 是一个指向 指向指针常量 的指针((int *const) *ptr),指针本身不是常量,所以结果为 false

const int (*)[1] 是一个指向包含 常量数组 的指针,指针本身并不是常量,所以结果为 false

const int *[1] 是一个包含指向 常量指针 的数组(const int *ptr[1]),数组元素是常量指针,所以结果为 false

const int[1][1] 是一个二维数组,其中的元素是常量,所以结果是 true

加载中...
此页面数据所有权由区块链加密技术和智能合约保障仅归创作者所有。