0%

在C语言中重用代码的方式就是拷贝代码、修改代码。C++中代码重用的方式之一就是采用继承。继承是面向对象程序设计中重要的特征,可以说,不掌握继承就等于没有掌握面向对象的精华。通过继承,我们可以用原有类型来定义一个新类型,定义的新类型既包含了原有类型的成员,也能自己添加新的成员,而不用将原有类的内容重新书写一遍。原有类型称为“基类”或“父类”,在它的基础上建立的类称为“派生类”或“子类”。

继承和派生的定义

当一个派生类继承一个基类时,需要在派生类的类派生列表中明确的指出它是从哪个基类继承而来的。类派生列表的形式是在类名之后,大括号之前用冒号分隔,后面紧跟以逗号分隔的基类列表,其中每个基类前面可以有访问修饰限定符,其形式如下:

1
2
3
4
5
6
7
class Derived
:public A
,protected B
,private C
{

};

Read more »

命名空间回顾

作用域可以分为类作用域、类名的作用域以及对象的作用域几部分内容。
在类中定义的成员变量和成员函数的作用域是整个类,这些名称只有在类中(包含类的定义部分和类外函数实现部分)是可见的,在类外是不可见的,因此,可以在不同类中使用相同的成员名。
另外,类作用域意味着不能从外部直接访问类的任何成员,即使该成员的访问权限是public,也要通过对象名来调用,对于static成员函数,要指定类名来调用。

和函数一样,类的定义没有生存期的概念,但类定义有作用域和可见域。使用类名创建对象时,首要的前提是类名可见,类名是否可见取决于类定义的可见域,该可见域同样包含在其作用域中,类本身可被定义在3种作用域内,这也是类定义的作用域。

Read more »

运算符重载的意义

C++预定义中的运算符的操作对象只局限于基本的内置数据类型,但是对于我们自定义的类型是没有办法操作的。但是大多时候我们需要对我们定义的类型进行类似的运算,这个时候就需要我们对这么运算
符进行重新定义,赋予其新的功能,以满足自身的需求。

Read more »

一般来说,类的私有成员只能在类的内部访问,类之外是不能访问它们的。但如果将其他类或函数设置为类的友元(friend),就可以访问了。用这个比喻形容友元可能比较恰当:将类比作一个家庭,类的private成员相当于家庭的秘密,一般的外人是不允许探听这些秘密的,只有friend(朋友)才有能力探听这些秘密。
友元的形式可以分为友元函数友元类.
在类中的生命方式如下:

1
2
3
4
5
6
7
class 类名
{
//...
friend 函数原型;
friend class 类名;
//...
}

Read more »

1. C风格字符串

字符串处理在程序中应用广泛,C风格字符串是以’\0’(空字符)来结尾的字符数组。对字符串进行操作的C函数定义在头文件或中。常用的库函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//字符检查函数(非修改式操作)
size_t strlen( const char *str );//返回str的长度,不包括null结束符
//比较lhs和rhs是否相同。lhs等于rhs,返回0; lhs大于rhs,返回正数; lhs小于rhs,返回负数
int strcmp( const char *lhs, const char *rhs );
int strncmp( const char *lhs, const char *rhs, size_t count );
//在str中查找首次出现ch字符的位置;查找不到,返回空指针
char *strchr( const char *str, int ch );
//在str中查找首次出现子串substr的位置;查找不到,返回空指针
char *strstr( const char* str, const char* substr );
//字符控制函数(修改式操作)
char *strcpy(char *dest, const char *src);//将src复制给dest,返回dest
char *strncpy(char *dest, const char *src, size_t count);
char *strcat( char *dest, const char *src );//concatenates two strings
char *strncat( char *dest, const char *src, size_t count );

在使用时,程序员需要考虑字符数组大小的开辟,结尾空字符的处理,使用起来有诸多不便。

Read more »

1. 对象的组织

有了自己定义的类,或者使用别人定义好的类创建对象,其机制与使用int等创建普通变量几乎完全一致,同样可以创建const对象、创建指向对象的指针、创建对象数组,还可使用new和delete等创建动态对象。

1.1 const 对象

类对象也可以声明为const对象,一般来说,能作用于const对象的成员函数除了构造函数和析构函数,便只有const成员函数了,因为const对象只能被创建、撤销以及只读访问,改写是不允许的.

1.2 指向对象的指针

对象占据一定的内存空间,和普通变量一致, C++ 程序中采用如下形式声明指向对象的指针:

1
类名 *指针名 [=初始化表达式];

初始化表达式是可选的,既可以通过取地址(&对象名)给指针初始化,也可以通过申请动态内存给指针初始化,或者干脆不初始化(比如置为nullptr),在程序中再对该指针赋值。
指针中存储的是对象所占内存空间的首地址。

1.3 对象数组

对象数组和标准类型数组的使用方法并没有什么不同,也有声明、初始化和使用3个步骤。

1.4 堆对象

和把一个简单变量创建在动态存储区一样,可以用new和delete表达式为对象分配动态存储区,在复制构造函数一节中已经介绍了为类内的指针成员分配动态内存的相关范例,这里主要讨论如何为对象和对象数组动态分配内存。

Read more »

1. 特殊的数据成员

在C++的类中,有4种比较特殊的数据成员,他们分别是常量成员引用成员类对象成员静态成员,他们的初始化与普通数据成员有所不同。

Read more »

This 指针

我们通过创建的对象调用成员函数之后,每个对象都能正确地访问相应的数据成员,就是通过this指针实现的。
在类中定义的非静态成员函数都有一个隐含的this指针,代表当前对象本身,作为成员函数的第一个参数,由编译器自动不全。如下:

1
2
3
4
5
6
void Point::print(Point *const this)
{
cout << "(" << this->_ix
<< "," << this->_iy
<< ")" << endl;
}

Read more »

XFFT

1. 概述

FFT IP计算N点正向DFT或逆向DFT(IDFT),其中N可以是2的m次方,m的取值范围是3-16。

计算 FFT 时可使用三种算术选项:

• Full-precision unscaled arithmetic
• Scaled fixed-point, where you provide the scaling schedule
• Block floating-point (run time adjusted scaling)

点数N、正向或逆向变换的选择、缩放计划和循环前缀长度可以在运行时进行配置。变换类型(正向或逆向)、缩放计划和循环前缀长度可以在逐帧的基础上进行更改。更改点数将重置核心。

image-20231113172757836

Read more »

拷贝构造函数

C++中经常会使用一个变量初始化另一个变量,如

1
2
int x = 1;
int y = x;

我们希望这样的操作也能作用于自定义类类型,如

1
2
Point pt1(1, 2);
Point pt2 = pt1;

这两组操作是不是一致的呢?第一组好说,而第二组只是将类型换成了Poin类型,执行Point pt2 = pt1;语句时,pt1对象已经存在,而pt2对象还不存在,所以也是这句创建了pt2对象,既然涉及到对象的创建,就必然需要调用构造函数,而这里会调用的就是复制构造函数,又称为拷贝构造函数

Read more »