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;
}
答案:
點擊查看答案
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();
}
答案:
點擊查看答案
121解釋:
即使 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();
}
答案:
點擊查看答案
AAABBAAB解釋:
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]>;
}
答案:
點擊查看答案
0110001解釋:
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
。