你真的懂C++吗?

mariocanfly / 2024-10-13 / 原文

看看下面的代码,你真的懂C++吗?

#define N 2
#define M N + 1
#define NUM (M + 1) * M / 2
int main(){
    std::cout << NUM;
    return 0;
}
// 输出结果为 8, 展开过程如下
// (M + 1) * M / 2
// (N + 1 + 1) * N + 1 / 2
// (2 + 1 + 1) * 2 + 1 / 2
//  4 * 2 + 0
//  8

cout << sizeof(i++) << endl; //代码执行之后,i并没有加1

#include <algorithm>
#include <iostream>
using namespace std;
class Animal {
  public:
    virtual void eat() const {
        cout << "Animal eats" << endl;
    }
    virtual ~Animal(){}
};

class Dog : public Animal {
  public:
    virtual void eat() {
        cout << "Dog eats" << endl;
    }
    virtual ~Dog(){}
};

int main() {
    Animal *animal = new Dog();
    Dog *dog = new Dog();
    animal->eat();
    dog->eat();
    delete animal;
    delete dog;
    return 0;
}
/*
上面的代码输出为:
Animal eats
Dog eats
如果把第一个Animal类的const去掉,就会输出
Dog eats
Dog eats
这是因为C++多态规定,基类和派生类中同名虚函数的函数名、返回值类型、函数参数个数及参数类型等必须完全相同。
如果基类的虚函数后面没有加const,派生类同名的函数后面加了const,那么派生类的函数没有起到虚函数的作用。
*/

int number = 1;
auto func1 = [=]() { return number; };
auto func2 = [&]() { return number; };
number++;
std::cout << func1() << ' ' << func2();  //输出 1 2

#include <iostream>
using namespace std;

double Up(double x) { return 2.0 * x; }
void R1(const double &rx) { cout << "const double & rx" << endl; }
void R1(double &&rx) { cout << "double && rx" << endl; }

int main()
{
    double w = 10.0;
    R1(w + 1);  // 输出 double && rx
    R1(Up(w));  // 输出 double && rx
    return 0;
}

auto myTuple = make_tuple<int,int,bool,char>(1,2,true,'C');
auto otherTuple = make_tuple<int,int,bool,char>(1,3, true, 'C' );
cout << sizeof(myTuple) << endl;  //输出 12, 不同机器结果不同
cout << tuple_size<decltype(myTuple)>::value << endl;  //输出元素数量 4

#include <iostream>

void Foo(const int &) {std::cout << "const l-ref" << std::endl;}
void Foo(int &) {std::cout << "l-ref" << std::endl;}
void Foo(int &&) {std::cout << "r-ref" << std::endl;}

template <typename ...Args> 
void ForwardRef(Args&& ...args) {
    Foo(std::forward<Args>(args)...);
}
int main(){
    ForwardRef(1); //输出r-ref
    int x = 1; ForwardRef(x); //输出l-ref
    int& y = x; ForwardRef(y); //输出l-ref
    const int& z = x; ForwardRef(z); //输出const l-ref
    return 0;
}

int a = 5;
static int b = 3;
auto funca = [=]() mutable {
    ++a; return a;
};
auto funcb = [=]() mutable {
    ++b; return b;
};
cout << funca() << " " << funcb() << endl; // 输出 6 4
cout << funca() << " " << funcb() << endl; // 输出 7 5
cout << a << " " << b << endl;             // 输出 5 5

enum Status {GOOD = -1, BAD, UNKNOWN};
cout << UNKNOWN << endl; //输出1
cout << static_cast<Status>(static_cast<int>(UNKNOWN) - 1) << endl;

#include <iostream>
using namespace std;
class Base {
  public:
    Base(int a) : varA(a) {}
    int varA;
};
class Derived : public Base {
  public:
    int varB;
    int varC;
    Derived(int a, int c) : varC(c), Base(a), varB(varA + varC) {}
};

Derived derived(1, 10); // 全局变量

int main() {
    cout << derived.varA << " " << derived.varB << " " << derived.varC << " " << endl;
    // 输出 1 1 10
    // 按照声明的顺序初始化而不是列表的顺序,这里初始化顺序是 varA,varB,varC,由于varB要被赋值为varA + varC时,
    // varC还没有赋值,所以此时varC = 0,varB被赋值为varA=1
    // 但是,把 Derived derived(1, 10) 放到int main()里面,情况又会不一样,这个我也解释不了。
    return 0;
}


#include <iostream>
class BaseException {};
class DerivedException:public BaseException {};
int main() {
    try {
        BaseException* except = new DerivedException();
        throw *except;
    } catch (DerivedException&) {
        std::cout << "DerivedException";
    } catch (BaseException&) {
        std::cout << "BaseException";
    } catch (...) {
        std::cout << "other Exception";
    }
    // 输出 BaseException
}

假设有以下代码:

class MyData {
public:
	MyData() : value(5) {}
private:
	int value;
};

void Func()
{
std::vector<MyData> myVector;
// ……对myVector进行了一些操作
____ // 想要添加一个元素到myVector中
}

横线处的代码想要添加一个MyData对象到myVector容器中,并且要求添加的这个MyData对象中value成员的值是5。下面代码可以正确完成这个动作:

myVector.push_back(MyData());
myVector.insert(myVector.end(), MyData());
myVector.resize(myVector.size() + 1);
//但是当myVector为空时,*(myVector.end()) = MyData(); 会报错

const int a = 128;
//以下都是无法通过的代码:
int * const b = &a;
int *b = &a;
int &b = a;
//以下是可以通过的代码:
const int &b = a;
const int *b = a;
int const *b = a;

//拷贝构造、移动构造、拷贝赋值、移动赋值你会写吗?
class A {
public:
    A() {
        cout << "Default constructor" << endl;
    }
    A(const A& a) {
        cout << "Copy constructor" << endl;
    }
    A(A&& a) {
        cout << "Move constructor" << endl;
    }
    A& operator=(const A& p) {
        cout << "Copy assign" << endl;
    }
    A& operator=(A&& other) {
        cout << "Move assign" << endl;
    }
};