文章目录
vector
返回一个空的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使用
c++中如果有一些函数被频繁掉用,可以使用inline关键字定义一个方法,这样这个方法就变成了内敛函数,使用内联函数的地方会在运行的时候被替换为内联函数的方法体,通过这种方式减少函数栈的调用。
使用限制:
- inline只适合涵数体内代码简单的函数数使用,不能包含复杂的结构控制语句例如while、switch,并且内联函数本身不能是直接递归函数(自己内部还调用自己的函数);
- 使用内联函数会增大代码体积,消耗更多的内存
inline float cube(const float a) { return a * a * a; }
->符号
c++中 ->用于指针上用来提取成员变量
ListNode *dummyHead = new ListNode(0);
cout << (*dummyHead).val << endl;
cout << dummyHead->val << endl;
C++中基本类型的数组使用的时候需要初始化,不然数组中的值不确定
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++ auto关键字
c++11开始后的auto关键字的使用:
- 声明变量时根据初始化表达式自动推断该变量的类型
- 声明函数时函数返回值的占位符
比如遍历一个容器的时候,可以使用auto快速遍历:
std::vector<int> vect;
for(auto it = vect.begin(); it != vect.end(); ++it)
{ //it的类型是std::vector<int>::iterator
}
// 或者
std::make_shared使用
查看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;
c++中基本类型的字节数
| 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就是一个传入的参数的别名
}
extern关键字
c++中变量分为声明和定义两个阶段:
- 当使用extern 声明一个全局变量的时候比如:extern int j; 表示该变量定义于其它单元。
- 当使用extern定义一个变量的时候,如:extern const int J = 10; 会让该变量拥有外部链接,否则该变量只有内部链接。
- 当使用extern “C” 修饰代码块或者声明的时候例如,每一个jni方法前面的extern “c” 表明后面的代码块使用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
c++中的friend用法
友元类:定义一个类时,主动声明哪些类或者函数是他的朋友,可以对friend类提供对他们自身的private和protected变量的访问特权
- 将类声明为自己的有元,这样这个类就可以访问自己的私有或者private变量
A.hpp
#ifndef __A
#define __A
#include <stdio.h>
#include <iostream>
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 <stdio.h>
#include <iostream>
#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
- 友元函数,表示这个函数可以访问到当前类的private和protected成员
修改上面的代码:
修改A.hpp中的代码:
// 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 <stdio.h>
#include <iostream>
#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
c++中使用new和不使用new创建类对象的区别
- c++中使用new创建对象,使用完后需要使用delete删除,可以一处创建然后在多处调用
CTest* pTest = new CTest();
delete pTest;
使用new创建的对象使用一个指针来接收
- new创建对象使用的是堆空间,不用new定义类对象的方式使用的是栈空间,栈空间当当前函数结束的时候,栈用的内存会被系统自动释放。
typedef 声明类型
c++中我们可以使用typedef来声明一个新的类型名,用新的类型名称来代替我们的类型:
typedef int Integer; // 使用Integer标识符来代表int类型
typedef struct
{
int age;
int height;
int weight;
} HUMAN; // 这里使用HUMAN是新的类型的名称,而不是机构体的变量名
HUMAN per1;
per1.age = 10;
template使用
模版是泛型编程的基础,使用模版我们可以实现泛型编写函数或者类:
泛型函数:
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
c++中function使用
使用function定义一个函数
// [&]表示以引用方式捕获块外的所有变量
function<int(int, int)> dfs = [&](int start, int end)
{
};
more:https://www.cnblogs.com/ChinaHook/p/7658411.html
c++中lambda表达式中的=和&的区别
c++lambda在捕获外部参数的列表中[=]表示是值传递,会使用对应的拷贝构造函数,[&]表示以引用方式处理外部变量。
using
- 使用命名空间:
// 在代码中定义命名空间
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;
static 变量
- 在修饰局部变量的时候,static 修饰的静态局部变量只执行初始化一次,而且延长了局部变量的生命周期,直到程序运行结束以后才释放。
- static修饰全局变量的时候,这个全局变量只能在本文件中访问,不能在其它文件中访问,即便是 extern 外部声明也不可以。
- static 修饰一个函数,则这个函数的只能在本文件中调用,不能被其他文件调用。
unique_ptr
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
c 和 c++ 中动态分配内存的方式差异
- new 是运算符,malloc是函数
- new 可以重载,malloc不可以重载
- malloc开辟空间失败返回NULL,new 分配空间失败,抛出bac_alloc异常,
malloc和free是c中的函数,因此在c++中无法执行构造和析构函数。
左右值
左值(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对象。
位置长度的数组也属于一种不完整类型。


被折叠的 条评论
为什么被折叠?



