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
BQ029#
#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
121Explain:
即使 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
AAABBAABExplain:
C *const p1
中 const 修饰 p1
指针,所以 s
对象的成员变量 p1
调用 foo
时会使用非 const
版本,C const *p2
中 const
修饰 *p
(C 类)对象,所以 s
对象的成员变量 p2
调用 foo
时会使用会使用 const
版本。
r
是对象 s
的常量引用,const
改变了成员 v
的行为,因为 std::vector
对 operator[]
进行了重载,常量对象调用是返回常量引用的版本,返回的也是常量引用,因此调用 foo
是 const
版本。
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
0110001Explain:
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
。