C++基础

C++ 基础



前言


一、函数

1、三种函数相关的语言特性:

  • 默认实参
  • 内联函数
  • constexpr函数

(1)默认实参作为形参的初始值出现在参数列表中

string screen( int height, int width = 65, char background =' ');  // 

(2)内联函数 inline
编译器会在每处调用内联函数的地方将内联函数的内容展开,避免因函数调用做出对现场进行压栈保存、并在调用结束后出栈恢复现场所用的开销。

inline string & shorterString(const string &s1, const string &s2){
	return s1.size() <= s2.size() ? s1 : s2;
}
  • 定义在类内部的成员函数是自动inline的
    (3)constexptr函数是能用于常量表达式的函数。
    ①constexptr函数的返回值及所有形参的类型都得是字面值类型;
    函数体中有且仅有一条return语句。
    ③constexptr函数被隐式地指定为内联函数。

2、预处理帮助

  • assert预处理宏

  • NDEBUG预处理变量

(1)assert预处理宏:assert宏使用一个表达式作为它的条件:

assert(exptr);

如果exptr为假,assert输出信息并终止程序;如果exptr为真,assert什么也不做。

(2)NDEBUG预处理变量:定义NDEBUG可关闭调试状态,避免检查各种条件所需的运行时开销。

#define NDEBUG

可以使用NDEBUG编写条件调试代码

#ifndef NDEBUG
	.... //如果NDEBUG未定义,则将会执行此段代码;否则将会忽略此段代码
#endif

assert的行为依赖于NDEBUG变量,如果定义了NDEBUG,则assert什么都不做;默认状态下没有定义NDEBUG。

3、函数指针:函数指针指向函数

函数的类型由返回类型和形参类型共同决定,与函数名无关。因此在声明函数指针的时候,直接用指针替换函数名:

bool lengthCompare(const string &, const string &); //函数
bool (*p)(const string &, const string &);//函数指针
//函数指针赋值
p = lengthCompare;//p直线名为lengthCompare的函数
p = &lengthCompare;//将lengthCompre函数的地址赋值给p指针
//通过指针调用函数
bool b1 = p("hello", "good"); 
bool b2 = (*p)("hello", "good");
bool b3 = lengthCompare("hello", "good");

函数指针作形参:

void useBigger(const string &s1, const string &s2,
bool p(const string &, const string &));//函数指针作形参
//等价声明:
void useBigger(const string &s1, const string &s2,
bool (*p)(const string &, const string &));

二、使用步骤

1.类

1.1 构造函数

  • 默认构造函数
  • 拷贝构造函数

(1)默认构造函数:在类没有显示声明任何构造函数时,编译器会自动生成默认构造函数(合成构造函数)。

通常需要自己定义默认构造函数:
①在声明其他类型的构造函数之后,编译器不会生成合成默认构造函数,需自己定义。
②当类的内置类型或者符合类型的成员都被赋予类内初始值时,该类才适合于使用合成默认构造函数;
③对于含有其他类类型的成员,且改类没有默认构造函数时,必须为当前类定义默认构造函数

【其他】构造函数不能用const来修饰,因为const修饰的是this指针,加上const之后就无法对对象的值进行赋值。

【其他】 构造函数不能用static修饰,因为静态函数没有this指针。

1.2 析构函数

【其他】定义一个类时,编译器将合成六个默认函数:

  • 构造函数
  • 拷贝构造函数
  • 析构函数
  • 赋值操作符重载
  • 取地址操作符重载
  • const修饰的取地址操作符重载

1.3 类的访问控制与封装

友元:类允许其他类或者非成员函数访问该类的非公有成员,方法是令其他类或者函数成为该类的友元。

声明说明:A用到类B的非公开成员,则在类B中声明A为友元函数/类:

class Sales_data{
	//友元函数
	friend Sales_data add_data(const Sales_data &, Sales_data &); //函数add_data()访问Sales_data的成员,此处友元声明仅指定访问权限
	// 友元类
	friend class Cost_data;//Cost_data类访问Sales_data的承运
public:
	Sales_data() = default;
	...
private:
	double revenue = 0.0;
};
Sales_data add_data(const Sales_data &, Sales_data &);//类外声明/定义(友元)函数

为了使友元对用户可见,通常在类外需要再专门对函数进行一次声明。

// 友元成员函数
class A;//B中依赖于A,故在B之前声明A
class B{
public:
	void set_show(int x, A&a);
	...
};
class A{
	friend void B::set_show(int x, A&a);//友元成员函数声明
public:
	...
};

2.动态内存

2.1直接管理内存 new、delete

2.2智能指针

指向动态内存的普通指针要通过delete销毁该对象并释放与之关联的内存。
显示释放内存够很容易出现问题:忘记释放内存——产生内存泄露;在尚有指针引用的情况下释放指针——产生引用非法的内存指针。

智能指针的作用是负责自动释放所指向的对象。可更容易、更安全地使用动态内存。

  • shared_ptr 允许多个指针指向同一个对象
  • unique_ptr 独占所指向的对象
  • weak_ptr 是一种弱引用,指向shared_ptr所管理的对象

智能指针也是模板,创建智能指针时需要提供指针可以指向的类型:

shared_ptr<string> p1;//指向string类型的智能指针
shared_ptr

每个shared_ptr都有一个关联的计数器用于进行引用计数(记录有多少个其他的shared_ptr指向相同的对象)。

拷贝shared_ptr会使计数器递增;

赋值会使 右值 指向对象的引用计数递增,递减 左值 原来指向对象的引用计数

// 智能指针定义及初始化方式一:
auto r = make_shared<int>(42);//构建一个shared_ptr r,r指向的int类型对象只有一个引用(r本身)
r =q;//给r赋值,令r指向另一地址
	// q的引用计数递增
	// r原来指向对象的引用计数递减
	// r指向新的对象

shared_ptr计数器变为0时,会通过析构函数释放所管理的对象的内存。

// 智能指针的定义及初始化方式二:
shared_ptr<int> (new int(42)); // 因为智能指针的构造函数是显示的explicit,必须使用直接初始化形式
shared_ptr<int> = new int(42); // 错误
unique_ptr

某个时刻只能有一个unique_ptr指向一个给定的对象。unique_dir被销毁时,它指向的对象也被销毁。

定义:

unique_ptr<int> p1;//定义指向一个int类型对象的unique_ptr
unique_ptr<int> p2(new int(42));//定义并显示初始化

unique_ptr 不支持 普通拷贝 或 赋值 操作

可通过releasereset将指针的所有权从一个非const的unique_ptr转移给另一个unique_ptr:

unique_ptr<string> p2(p1.release());//p2被初始化为p1保存的指针,p1置空
p2.reset(p3.release());//将所有权从p3转移给p2

2.3

shared_ptrnew结合使用

在这里插入代码片

代码如下(示例):

data = pd.read_csv(
    'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())

该处使用的url网络请求的数据。


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值