C与C++在函数和数据的比较
C
Data(struct)
数据是一个类型 -> 根据数据的类型创建出真正的数据
Function
函数就是用来处理数据的
缺陷:
语言没提供关键字.所以数据是全局的 -> 各个函数都可以处理数据
C++
Data
将数据和处理这些数据的函数包裹在一起,其他函数看不到其他函数处理的数据
Function
将来以class
为一个object
创建对象
C++ programs代码的基本形式
.h
-> .cpp
-> .h(Standard Library)
自己写的头文件引入的时候用双引号""
标准库的头文件引入的时候使用尖括号<>
头文件中防卫式声明
#pragma once
/*
无指针的类,单一的类,不和其他类有关联的
*/
#ifndef __COMPLEX__ // guard 防卫式声明 -> 不要有重复的include动作
#define __COMPLEX__
#endif // __COMPLEX__
Header
头文件布局
-
0 -> 前置声明(
forward declarations
) -
1 -> 类声明(
class declarations
) -
2 -> 类定义(
class definition
)
示例代码:
#pragma once
/*
无指针的类,单一的类,不和其他类有关联的
*/
#ifndef __COMPLEX__ // guard 防卫式声明 -> 不要有重复的include动作
#define __COMPLEX__
/*
class head
class body
body内函数
body外函数
*/
class complex // class head
{
public:
complex (double r = 0, double i = 0)
: re(r), im(i) { }
complex& operator += (const complex&); // 这是函数声明,没有定义内容
double real() const { return re; } // 直接定义了函数
double imag() const { return im; }
private:
// 实部虚部类型
double re, im;
friend complex& __doapl(complex*, const complex&);
};
#endif // __COMPLEX__
C++类型模板
如果需要声明一个复数类型是float
那么有99%
的代码会是重复的,那么这个时候就引入了C++
模板的概念 -> typename T
示例代码:
#pragma once
/*
无指针的类,单一的类,不和其他类有关联的
*/
#ifndef __COMPLEX__ // guard 防卫式声明 -> 不要有重复的include动作
#define __COMPLEX__
/*
class head
class body
body内函数
body外函数
*/
template<typename T> // 具体使用的时候才指明类型
class complex // class head
{
public:
complex (double r = 0, double i = 0)
: re(r), im(i) { } // 构造函数
complex& operator += (const complex&);
double real() const { return re; } // inline function
double imag() const { return im; }
private:
// 实部虚部类型
T re, im;
friend complex& __doapl(complex*, const complex&);
};
#endif // __COMPLEX__
{
complex<double> c1(2.5, 1.5);
complex<int> c2(2, 6);
// 这两个使用的T类型不一样,一个是double类型,一个是int类型
}
inline(内联)函数
函数在class
内定义就是inline
*
如果函数太复杂,则没有办法inline
是否真的变成inline
由编译器决定
access level(访问级别)
public
为外界可以看到
private
为内部可以看到,外部看不到 -> 数据部分内部看到
所有的数据都应该声明为private
constructor(构造函数)
构造函数示例:
complex (double r = 0, double i = 0)
: re(r), im(i) { }
这就是一个构造函数,默认参数为(0, 0),他会给re
和im
两个部分赋值
构造函数的特点:
构造函数名称一定要和类的名称相同
构造函数不需要有返回类型
对于构造函数的辅助应该使用构造函数的特有语法 -> 初始化、初值列 -> 不要再构造函数体内进行赋值
示例代码:
complex (double r = 0, double i = 0) : re (r), im (i) { } // 这就是初始化、初值列
complex (double r = 0, double i = 0) { re = r; im = i; } // 这就不太好
结果虽然相同但是在赋值阶段的时间点不同
构造函数的重载(overloading)
以构造函数举例是因为构造函数必须和类名相同
函数重载是指同一个类的不同构造方式由函数创作者决定.这三种构造方式的函数名称都是相同的,这个就是函数的重载
构造函数私有化(单例设计模式)
示例代码:
#pragma once
#ifndef __SINGLETON__
#define __SINGLETON__
class A
{
public:
static A& getInstance();
setup() {}
private:
A();
A(const A& rhs);
};
A& A::getInstance()
{
static A a;
return a;
}
#endif // !__SINGLETON__
const member functions (常量成员函数)
class
当中不会改变数据的函数需要在{}
前加上const
-> 表示不改变里面数据的内容
参数传递
-
pass by value
-> 整包传递(value
多大都传过去 -> 压到栈空间进行传递) -
pass by reference(引用)
-> 传引用就相当于传指针 -> 很快.但是形式很漂亮
尽量不要pass by value
-> c
当中可以传递指针 -> 最好所有的参数传递都传引用
需要注意传递字符的时候
如果需要传递引用并且希望对方不能修改内容,加入不可变关键字const
-> 如果对方改了编译就会出错
返回值传递
-
return by value
-
return by reference(to const)
返回值传递也尽量by reference
friend(友元)
friend
可以取到private
变量
相同class
的各个object
互为friends
(友元)
同一个class
构成的对象互为friend
所以可以直接调用另一个class
里面的private
变量
class complex
{
public:
complex (double r 0, double i = 0) : re(r), im(i) { }
int func(const complex& param) { return param.re + param.im; }
};
{
complex c1(2, 1);
complex c2;
c2.func(c1); // c1、c2互为友元因为c1和c2是同一个class出来的object
}
什么情况下不能够return by reference
:
示例代码:
#include <iosteam>标签:__,函数,double,C++,complex,数据,class,构造函数 From: https://www.cnblogs.com/JunkingBoy/p/18133211
int main()
{
// 下面的add方法当中就不能够传指针(引用),因为出了函数以后的作用域声明的result就被销毁了.
}
int add(int a, int b)
{
int result = a + b;
return result;
}