C++除了支持struct
以外,还支持class
,不需要像C那样用typedef
的方式定义一个struct
。
在C++中,struct
和class
几乎没有任何区别,与C不同,在C++里,struct
可以拥有成员函数。其与class
的区别主要由以下几点:
- 默认访问权限:
struct
作为数据结构的实现体,它默认的数据访问控制是public
的,而class
作为对象的实现体,它默认的成员变量访问控制是private
的; - class 继承默认是 private 继承,而 struct 继承默认是 public 继承;
在工程中,一般用struct
定义“纯数据”的类型,只包含较少的辅助成员函数,用class
定义“拥有复杂行为”的类型。
下面是一个例子
#include
/* 定义结构体Point */
struct Point {
int x, y;
/* 构造函数简单写法 */
Point(int x = 0, int y = 0) : x(x), y(y) {}
// 构造函数还可以写成下面的形式
// Point(int x = 0, int y = 0) { this->x = x, this->y = y };
};
/* 定义Point “+” 运算符 */
Point operator + (const Point& A, const Point& B) {
return Point(A.x + B.x, A.y + B.y);
}
/* 定义Point “-” 运算符 */
Point operator - (const Point& A, const Point& B) {
return Point(A.x - B.x, A.y - B.y);
}
/* 定义Point流输出方式 */
std::ostream& operator << (std::ostream& out, const Point& p) {
out << "(" << p.x << "," << p.y << ")";
return out;
}
int main(){
Point a, b(1, 2);
a.x = 3;
std::cout << a + b << "\n" ;
return 0;
}
上述代码中,结构体Point
中定义了一个函数Point()
,没有返回值,是结构体Point
的构造函数。构造函数是在声明变量(结构体/对象)时调用的。Point a, b(1, 2)
分别调用了Point()
和Point(1, 2)
;Point(int x = 0, int y = 0)
中“=0”的含义是默认值为0,Point()
相当于Point(0, 0)
,: x(x), y(y)
是一个简单的写法,表示把成员变量x
初始化为参数x
,变量y同理。也可以写成:
Point(int x = 0, int y = 0) { this->x = x, this->y = y };
这里的this
是指向当前对象的指针。
接下来的代码分别定义了结构体Point
的加法、减法和流输出 *** 作,使a
和b
可以进行加减 *** 作和cout <<
*** 作。
定义一个求数组和的函数sum
(),一般的写法如下:
/* 普通的sum函数,比较局限,只能求整数数组的和 */
int sum(int* begin, int* end) {
int* p = begin;
int ans = 0;
for (int *p = begin; p != end; p++)
ans += *p;
return ans;
}
这个函数没有语法错误,但是比较局限,它只能求整数数组的和,无法求double
、float
等类型数组的和,更别提Point
类型的和了。可以把sum()函数进行如下改进:
/* 使用模板改进sum函数,改进后可以求double、Point等类型的和 */
template<typename T>
T sum(T* begin, T* end) {
T* p = begin;
T ans = 0;
for (T *p = begin; p != end; p++)
/* 注意这里把 ans += *p; 改成了ans = ans + *p; */
/* 这样做的原因是Point类型没有定义“+=”运算符 */
ans = ans + *p;
return ans;
}
注意改进后的sum()
函数与之前sum()
的不同,将int
替换成了模板T。特别注意把 ans += *p;
改成了ans = ans + *p;
,因为Point
在之前并未定义+=
*** 作。
这样,可以使用sum()
函数给double
数组和Point
数组进行求和了。
int main()
{
double a[] = { 1.1, 2.2, 3.3, 4.4 };
std::cout << sum(a, a + 4) << std::endl;
Point b[] = { Point(1, 2), Point(3, 4), Point(5, 6), Point(7, 8)};
std::cout << sum(b, b + 4) << std::endl;
}
结构体和类也可以带模板。
上面Point
中的x
和y
是int
类型,有时也需要double
或者别的类型,+
和<<
的逻辑不变,可以用类似的写法把Point
变为模板:
/* Point结构体中带模板 */
template <typename T>
struct Point {
T x, y;
Point(T x = 0, T y = 0) :x(x), y(y) {}
};
/* 定义Point “+” 运算符 */
template <typename T>
Point<T> operator + (const Point<T>& A, const Point<T>& B) {
return Point(A.x + B.x, A.y + B.y);
}
/* 定义Point “-”运算符 */
template <typename T>
Point<T> operator - (const Point<T>& A, const Point<T>& B) {
return Point<T>(A.x - B.x, A.y - B.y);
}
/* 定义Point流输出方式 */
template <typename T>
std::ostream& operator << (std::ostream& out, const Point<T>& p) {
out << "(" << p.x << "," << p.y << ")";
return out;
}
这样,就可以同时使用int
类型和double
类型的Point
了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)