一些C++语法很难懂,比如左值、右值和std::move的关系,这时候如果有示例的话就好了。

[[nodiscard]]

[[nodiscard]] is an attribute introduced in C++17. It tells the compiler (and other developers) that the return value of a function (or a type) should not be ignored. The main idea is to prevent mistakes where a programmer accidentally calls a function but does not use its result, which might lead to logical errors or bugs.

// on a function
[[nodiscard]] int computeValue() {
    return 42;
}

// on a type
struct [[nodiscard]] Result {
    int code;
};
void example() {
    doWork(); // ⚠️ Warning: discarded a 'nodiscard' type
}

In C++20, you can provide a custom message:

[[nodiscard("You must use the result to avoid leaks!")]]
int* createResource();

If ignored, the compiler warning will include that message.

runtime_error
#include <stdexcept>  // for std::runtime_error
#include <iostream>

int main() {
    try {
        // Throw a runtime error with a message
        throw std::runtime_error("Something went wrong!");
    }
    catch (const std::runtime_error& e) {
        std::cout << "Caught runtime_error: " << e.what() << std::endl;
    }
    catch (...) {
        std::cout << "Caught an unknown exception" << std::endl;
    }

    return 0;
}
explicit pair construction
#include <vector>
#include <utility> // for std::pair
#include <string>

int main() {
    std::vector<std::pair<int, std::string>> vec;

    // Directly construct the pair inside emplace_back
    vec.emplace_back(1, "one");

    return 0;
}

一、执行

  • 如果实参是临时变量,形参不能是引用的形式。
  • static变量的唯一性是动态库级别的,不同库包含同一截代码的话就会有多份static实例。
01 运用先初始化的成员的值来初始化其它成员
#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

class Base
{
 public:
  int b;
  Base(int in)
  {
    b=in;
  }
};
class func
{
 public:
  ~func(){};
  func():a(1),b(func1())
  {
  }
  int func1()
  {
    return a+1;
  }
  
  int a ;
  Base b ;
  
};

int main(int argc,char** argv)
{
  func f;
  std::cout << f.b.b << std::endl;
  return 0;
} 
02 函数指针
/***** function and pointer *****/
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
std::ofstream os("123.txt");

class TS
{
 public:
  int fun8(int a, int b)
  {
    return a+b;
  }
};
int fun(int a, int b)
{
  int i = 0;
  int* c = &i;
  *c = a + b;
  std::cout << "001: " << *c <<std::endl;
  return *c;
}

int* fun3(int a, int b)
{
  int i = 0;
  int* c = &i;
  *c = a + b;
  std::cout << "002: " << *c <<std::endl;
  return c;
}

int main()
{
 int (*funcPtr)(int, int) = fun; // 创建一个返回值为 int 的函数指针
 funcPtr(1,2);
 std::cout << "003: " << &funcPtr << std::endl;
 
 std::cout << *fun3(1,5) << std::endl; // 函数的返回值为一个指针
 
 auto ff = &TS::fun8;
 TS tt;
 std::cout << "004: " << (tt.*ff)(3,2) << std::endl;
 std::cout << "005: " <&ff << std::endl;
 os << &ff ;
 
 std::cout << std::endl;
 const int x = 5, y = 6;
 const int* p = &x;
 y = x;
 std::cout <<  "006: " << *p << std::endl;
 return 0;
}
3
/***** right value and left value *****/
4
  • 编译时候类是知道自己有哪些no-virtual成员函数(编译器通过编码规则判断),并且下发所有被调用的成员函数首地址给了每一个对象,编译结束后,类不在关心自己有哪些成员函数,因为每一个对象都得到了分配,所以类中也就不用存贮函数的地址了.

  • 在成员函数体内,成员变量的访问是通过在后台计算与this指针的偏移来进行。但不同的系统、编译器,使用的内存布局不一定相同,因此在编程过程中不能假设类的内存布局。

5

由于引用不能为NULL,因此使用起来更安全。总体而言,请尽可能使用引用。但是,如果我们想编写同时使用C和C ++编译器进行编译的C代码,则必须限制使用指针。

6
#include <iostream>
#include <vector>
using namespace std;
 
vector<int> vec = { 1, 2, 3, 4, 5, 6 };
 
int main()
{
  for (auto n : vec)
  {
    cout << n << endl;
    vec.push_back(7);
  }
 
  system("pause");
  return 0;
}

在遍历容器的时候,在容器中插入一个元素导致迭代器失效了,因此,基于范围的for循环和普通的for循环一样,在遍历的过程中如果修改容器,会造成迭代器失效。因此,上述代码在运行时会崩溃。

7