返回一个空的vector
// C11以前
return vector<string>();
// c11起
return {};
class A
{
public:
A(int val)
{
x = val;
cout << " A is " << val << endl;
}
int x = 0;
};
class B : A
{
public:
B(int b) : A(b)
{
cout << " " << b << endl;
}
};
B类的构造函数后面的冒号表示掉用父类的构造函数
c++中如果有一些函数被频繁掉用,可以使用inline关键字定义一个方法,这样这个方法就变成了内敛函数,使用内联函数的地方会在运行的时候被替换为内联函数的方法体,通过这种方式减少函数栈的调用。
使用限制:
inline float cube(const float a) { return a * a * a; }
c++中 ->用于指针上用来提取成员变量
ListNode *dummyHead = new ListNode(0);
cout << (*dummyHead).val << endl;
cout << dummyHead->val << endl;
int a[100];
for (int i = 0; i < 10; i++)
{
cout << " i is " << a[i] << endl;
}
上面的代码运行结果如下,值会是个非法值。(之前一直在写java习惯了不初始化使用默认值,结果写c++基本代码都不会写)
i is 1107296256
i is 0
i is 131431020
i is 1
i is 131889808
i is 1
i is -281910792
i is 32766
i is 9277440
i is 1
c++11开始后的auto关键字的使用:
比如遍历一个容器的时候,可以使用auto快速遍历:
std::vector<int> vect;
for(auto it = vect.begin(); it != vect.end(); ++it)
{ //it的类型是std::vector::iterator
}
// 或者
查看c++官网参考
Allocates and constructs an object of type T passing args to its constructor, and returns an object of type shared_ptr that owns and stores a pointer to it (with a use count of 1).
make_shared 智能指针的一种,智能指针是用来管理指针的类,用来存储指向动态分配对象的指针。自动释放动态分配的对象。
std::shared_ptr<int> foo = std::make_shared<int>(10);
// same as:
std::shared_ptr<int> foo2(new int(11));
auto bar = std::make_shared<int>(20);
std::cout << "*foo: " << *foo << '\n';
std::cout << "*foo2: " << *foo2 << '\n';
std::cout << "*bar: " << *bar << '\n';
return 0;
make_shared 官方参考
float | 内存中占4个字节,有效数位是7位 |
double | 占8个字节,有效数位是16位 |
变量的前面加&表示取变量地址(赋值给指针), 如:int a = 0; int *pa = &a; a和pa是变量;*pa是指针;&a是取变量a的地址。
类型后面表示引用,引用即变量的别名。
例如:
int a = 0; int &ref = a;
例如我们在函数参数列表中定义形参为引用传递的方式:
void Fun(int &a){ // 这里的a就是一个传入的参数的别名
}
c++中变量分为声明和定义两个阶段:
例子:
我们要在A.cpp/h 中定一个全局变量,然后再B.cpp/h中使用
在A.cpp中定义一个全局变量
int testGLobalVal=100;
然后在B.cpp文件中使用extern进行声明:
extern int testGLobalVal;
然后在B.cpp中我们就可以使用该变量
参考:
https://www.runoob.com/w3cnote/cpp-static-usage.html
友元类:定义一个类时,主动声明哪些类或者函数是他的朋友,可以对friend类提供对他们自身的private和protected变量的访问特权
A.hpp
#ifndef __A
#define __A
#include
#include
using namespace std;
class A
{
friend class B;
public:
~A();
static void func()
{
cout << " this is in A " << endl;
}
private:
A(){};
static const A Test;
};
#endif
A中定义一个private的变量,将B声明为自己的友元,这样B中就可以访问A中的私有变量
B.hpp
#ifndef __B
#define __B
class B
{
public:
B();
void func();
};
#endif
友元类中定义的函数使用到了原始类的私有变量,那么就需要在友元类定义的文件中包含原始类定义的头文件,所以这里导入了A.hpp,
原始类的定义中(包含友元类声明的那个类A.hpp),就不需要包含友元类的头文件,也不需要在类定义前去声明友元类,因为友元类的声明自身就是一种声明(它指明可以在类外找到友元类)
B.cpp
#include
#include
#include "B.hpp"
#include "A.hpp"
using namespace std;
B::B()
{
cout << " construct a b val " << endl;
}
void B::func()
{
cout << " enter b " << endl;
A::Test.func();
}
int main()
{
B bb;
bb.func();
return 0;
}
输出:
construct a b val
enter b
this is in A
// A中声明B中的func1为友元函数
friend void B::func1();
修改B.hpp中的代码:
#ifndef __B
#define __B
class B
{
public:
B();
void func1();
void func2();
};
#endif
B.cpp
#include
#include
#include "B.hpp"
#include "A.hpp"
using namespace std;
B::B()
{
cout << " construct a b val " << endl;
}
void B::func1()
{
cout << " enter func1 " << endl;
A::Test.func();
}
void B::func2()
{
cout << " enter func2 " << endl;
// 这个函数调用的话会报错,因为只声明了func1为友元函数
// A::Test.func();
}
int main()
{
B bb;
bb.func1();
bb.func2();
return 0;
}
参考:https://blog.csdn.net/bandaoyu/article/details/111591588
CTest* pTest = new CTest();
delete pTest;
使用new创建的对象使用一个指针来接收
c++中我们可以使用typedef来声明一个新的类型名,用新的类型名称来代替我们的类型:
typedef int Integer; // 使用Integer标识符来代表int类型
typedef struct
{
int age;
int height;
int weight;
} HUMAN; // 这里使用HUMAN是新的类型的名称,而不是机构体的变量名
HUMAN per1;
per1.age = 10;
模版是泛型编程的基础,使用模版我们可以实现泛型编写函数或者类:
泛型函数:
template <typename T>
inline T const& Max (T const& a, T const& b)
{
return a < b ? b:a;
}
// 上面定义了一个比较大小的函数模版,这样我们在使用的时候可以传入不同的类型
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
string s1 = "Hello";
string s2 = "World";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
类模版
template <class T>
class Stack {
private:
vector<T> elems; // 元素
public:
void push(T const&); // 入栈
void pop(); // 出栈
T top() const; // 返回栈顶元素
bool empty() const{ // 如果为空则返回真。
return elems.empty();
}
};
// 在定义template中的方法的时候使用下面的方式:
template <class T>
void Stack<T>::push(T const &elem)
{
// 追加传入元素的副本
elems.push_back(elem);
}
...
参考:
https://www.runoob.com/cplusplus/cpp-templates.html
使用function定义一个函数
// [&]表示以引用方式捕获块外的所有变量
function<int(int, int)> dfs = [&](int start, int end)
{
};
more:https://www.cnblogs.com/ChinaHook/p/7658411.html
c++lambda在捕获外部参数的列表中[=]表示是值传递,会使用对应的拷贝构造函数,[&]表示以引用方式处理外部变量。
// 在代码中定义命名空间
namespace xxxxx;
// 使用我们定义的命名空间
using namespace xxxxx;
class T5Base
{
public:
T5Base() : value(55) {}
virtual ~T5Base() {}
void test1() { cout << "T5Base test1..." << endl; }
protected:
int value;
};
class T5Derived : private T5Base
{
public:
using T5Base::test1;
using T5Base::value;
void test2() { cout << "value is " << value << endl; }
};
使用using,我们可以访问private化的基类成员,因为using可以将在别处定义的名称 引入到using声明出现的区域:
Introduces a name that is defined elsewhere into the declarative region where this using-declaration appears.
参考链接:
https://www.runoob.com/cplusplus/cpp-inheritance.html
using value_type = _Ty
以后使用value_type value; 就代表_Ty value;
unique_ptr是一个独占型的智能指针,他不允许其他指针共享其内部的指针,不能通过赋值将一个unique_ptr赋值给另一个另一个。但可以通过函数返回给其他的unique_ptr,还可以通过std::move来转移到其他的unique_ptr,这样它本身就不再拥有原来指针的所有权了。
unique_ptr<T> my_ptr(new T); // 正确
unique_ptr<T> my_other_ptr = std::move(my_ptr); // 正确
unique_ptr<T> ptr = my_ptr; // 报错,不能复制
std::make_unique是c++14里加入的标准库,使用unique_ptr,只有一个智能指针管理资源。
参考:https://juejin.cn/post/7137133849430982693
左值(lvalue):左值表示了一个占据内存中某个可识别的位置(地址)的对象
右值(rvalue):右值表示了一个不表示内存中某个可识别位置(地址)的对象的表达式
int var;
var = 4;
上面的代码中,var 是一个具有内存位置的对象,他是左值,4 是一个临时变量是一个右值,
左值有内存地址,可以被修改,但是并不是所有的左值都可以被赋值,可以被赋值的左值称为可修改的左值:
const int a = 10; // 'a' 是左值
a = 10; // 但不可以赋值给它!
例如在上面代码中,a 是一个左值,但是 a 不能被赋值。
https://nettee.github.io/posts/2018/Understanding-lvalues-and-rvalues-in-C-and-C/
incomplete types (types that describe objects but lack information needed to determine their sizes).
不完整类型举例:
class base;
struct test;
这里只给出了 base 和 test 的声明,没有给出定义,不完整类只能用于定义指针或者引用,实例化的是指针或者引用本身,而不是base或者test对象。
位置长度的数组也属于一种不完整类型。