C++ primer plus笔记——第十章——类和对象

第十章——类和对象

  • 学习c++也有一段时间了,一直在工程应用上,也就是能用就行,没有系统地去学习,根据口碑是c++ primer更好,但是手头只有这本,记录一下学习中的收获。

1.面向对象编程

  • 面向过程的方法,首先考虑要遵循的步骤,然后考虑如何表示这些数据。
  • 面向对象的方法,从用户角度考虑,描述对象所需的数据以及描述用户和数据交互所需的操作

2.抽象与类

  • 类的设计尽量将公有接口和实现细节分开。和数据隐藏等一样,是一种封装。
  • 内联函数:如果一个函数是内联的,那么在编译的时候,编译器会把该函数的代码副本放置在每个调用该函数的地方。要求在每个使用内联函数的文件中定义,所以应将内联定义在类的头文件中。 (这点有疑问,可能使用的vs2017有只能链接程序,所以实验不出来)
    • 优点: 当函数体比较小的时候, 内联该函数可以令目标代码更加高效。
    • 缺点: 内联非常短小的存取函数通常会减少代码大小, 但内联一个相当大的函数将戏剧性的增加代码大小.
    • 结论: 不要内联超过 10 行的函数. 谨慎对待析构函数, 析构函数往往比其表面看起来要更长, 因为有隐含的成员和基类析构函数被调用,不要内联那些包含循环或 switch 语句的函数。

3.构造函数与析构函数

int year = 2001;
struct thing;
{
    
    
	char * pn;
	int m;
};
thing amabob = {
    
    "wodget", -23 };
Stock hot = {
    
    "nameOfCompany", 200, 2.2}//Stock 是之前定义的类,这个操作编译错误。

不能像初始化结构体那样初始化类的对象,因为数据部分的访问是私有的(如果设置为公有,就违背了OOP的思想)结构体和类区别之一吧。

  • 如果对象是const类型的话(const Stock tencent),调用的成员函数也必须是const类型的。
//这是函数声明
void show() const;
//这是函数定义
void show() const
{
    
    
	std::cout<<"lalala";
}
/*
否则将出现一下两条错误:
1. E1086 对象含有与成员 函数 "Stock::show" 不兼容的类型限定符	对象类型是:  const Stock

2. C2662	“void Stock::show(void)”: 不能将“this”指针从“const Stock”转换为“Stock &”
*/
  • C++11还可以将初始化列表的方法用于类
//三个参数意义分别为公司名称,购入股票数,股票的价格
Stock hot_tip = {
    
    "tencent", 100, 4.5}
Stock hot_tip {
    
    "tencent", 100, 4.5}
  • 杂记:c++函数的缺省值是在定义的时候还是在声明的时候定义呢?
    声明是用户可以看到的地方,用户相信这个特性。如果在定义的时候与声明不同的话就有问题,所以编译器禁止声明和定义的时候同时定义缺省值。
    报错:重定义默认参数
  • 默认实参需要在形参列表的结尾,否则会报错。

5.对象数组

//可以这样初始化
const int STKS = 4;
Stock stocks[STKS] = 
{
    
    
	Stock("a", 1.1, 2);
	Stock("b", 1.2,3);
	Stock("c", 1.3,4);
	Stock("d", 1.4,5);
}

6.类作用域

需要创建一个由所有对象共享的常量时,仅仅声明为const int 等类型是不行的。因为声明类只是描述了对象的形式,并没有创建对象。没有用于存储值的空间。具体方法有二

  • 方法一:在类中声明一个枚举。
class A
{
    
    
private:
	enum {
    
    Months = 12};
	...
  • 方法二:声明为静态变量例如 static const int

7.作用域内枚举

8.抽象数据类型 以栈为例。

作业:

注意的细节:

  • 1.一个类的名称一般都是首字母大写。

复习题5

/*
* 定义一个类来表示银行账户。数据成员包括储户姓名、账号(使用字符串)和存款。成员函数执行如下操作。
* 创建一个对象并将其初始化;
* 显示储户姓名、账号和存款;
* 存入参数指定的存款
* 取出参数指定的存款
*/
class BankCount
{
    
    
private:
	string name;
	long number;
	long deposit;
public:
	BankCount();//default constructor
	BankCount(std::string name,std::string number,long deposit);//constructor
	void show() const;
	bool save(int);
	bool withdraw(int);
};

编程练习 2

#include <iostream>
#include <string>
using namespace std;

class Person {
    
    
private:
	static const int LIMIT = 25;
	string lname;	//person's last name
	char fname[LIMIT];	//person's first name
public:
	Person(); //{ lname = "", fname[0] = '\0'; }//#1
	Person(const string&, const char*fn = "Hey,You.");//#2
	void show()const;	//first-last
	void FormalShow() const;//last-first
};
/*
Person::Person()
{ lname = "", fname[0] = '\0'; }//#*/
Person::Person()
{
    
    
	lname = "notDefined";
	strcpy_s(fname,"NULL");//字符串数组没有在声明的时候初始化的话,只能这么拷贝了。
	cout << "default constructor called.\n";
}
Person::Person(const string & lname_, const char* fname_)
{
    
    
	lname = lname_;
	strcpy_s(fname, fname_);
	cout << "constructor called.\n";
}
void Person::show() const
{
    
    
	cout << "name: " << fname << " " << lname << endl;//需要有string头文件才能直接cout
}
void Person::FormalShow() const
{
    
    
	cout << "name: " << lname << " " << fname << endl;//需要有string头文件才能直接cout

}
int main()
{
    
    
	Person noOne;
	Person me{
    
     "neo","lin" };
	noOne.show();
	me.show();
	system("pause");
}

编程练习5

//stack.h
#pragma once
#ifndef STACK_H_
#define STACK_H_

struct Customer {
    
    
	char fullname[35];
	double payment;
};

typedef Customer Item;

class Stack
{
    
    
private:
	enum{
    
    max=10};
	Item items[max];
	int top;
	double sum = 0;
public:
	Stack();//构造函数
	bool isEmpty() const;
	bool isFull() const;
	bool push(const Item & item);
	bool pop(Item & item);
	void show() const;
};
#endif

//stack.cpp
#include "stack.h"
#include <iostream>
Stack::Stack()
{
    
    
	top = 0;
}
bool Stack::isEmpty() const
{
    
    
	return top == 0;
}
bool Stack::isFull() const
{
    
    
	return top == max;
}
bool Stack::push(const Item & item)
{
    
    
	if (top < max)
	{
    
    
		items[top++] = item;
		return true;
	}
	else
		return false;
}
bool Stack::pop(Item & item)
{
    
    
	if (top > 0)
	{
    
    
		item = items[--top];
		sum += item.payment;
	}
	else
		return false;
}
void Stack::show() const
{
    
    
	for (int i = 0; i < top; ++i)
	{
    
    
		std::cout << "full name: "<< items[i].fullname << "\t" << "payment: " 
			<< items[i].payment << std::endl;
	}
	std::cout << "sum:" << sum << std::endl << std::endl;
}

//main.cpp
#include "stack.h"
#include <iostream>
Stack::Stack()
{
    
    
	top = 0;
}
bool Stack::isEmpty() const
{
    
    
	return top == 0;
}
bool Stack::isFull() const
{
    
    
	return top == max;
}
bool Stack::push(const Item & item)
{
    
    
	if (top < max)
	{
    
    
		items[top++] = item;
		return true;
	}
	else
		return false;
}
bool Stack::pop(Item & item)
{
    
    
	if (top > 0)
	{
    
    
		item = items[--top];
		sum += item.payment;
	}
	else
		return false;
}
void Stack::show() const
{
    
    
	for (int i = 0; i < top; ++i)
	{
    
    
		std::cout << "full name: "<< items[i].fullname << "\t" << "payment: " 
			<< items[i].payment << std::endl;
	}
	std::cout << "sum:" << sum << std::endl << std::endl;
}

第六题

#include <iostream>
#include <string>
#include "stack.h"
using namespace std;

class Move
{
    
    
private:
	double x;
	double y;
public:
	Move(double a = 0, double b = 0);
	void showmove() const;
	Move add(const Move & m) const;
	void reset(double a = 0, double b = 0);
};
Move::Move(double a, double b)
{
    
    
	x = a;
	y = b;
}
Move Move::add(const Move & m) const
{
    
    
	Move temp{
    
     this->x + m.x, this->y + m.y };
	return temp;
}
void Move::showmove() const
{
    
    
	cout << "x:" << x << "\ty:" << y << endl;
}
void Move::reset(double a, double b)
{
    
    
	x = a;
	y = b;
}
int main()
{
    
    
	Move m1{
    
     2.2,3.3 }, m2{
    
     4.4,5.5 };
	Move m3 = m1.add(m2);
	m3.showmove();
	system("pause");
}

第七题

/*
"aaa"的类型是const char *
获取其长度的方法是使用strlen函数
*/
#include <iostream>
#include <string>
#include "stack.h"
using namespace std;
class Plorg
{
    
    
private:
	char m_name[20];
	int m_CI;
public:
	Plorg();
	Plorg(const char *,int);//因为传入的为const类型的字符串数组,所以这里需要声明为const,不然不能匹配。
	void changeCI(int);
	void show() const;
};
Plorg::Plorg()
{
    
    
	strcpy_s(m_name, "Plorga");
	m_CI = 50;
}
Plorg::Plorg(const char* name, int CI)
{
    
    
	if (strlen(name) > 20)
	{
    
    
		cout << "name is too long, name set to default name\n";
		strcpy_s(m_name, "Plorga");
		m_CI = CI;
	}
	else
	{
    
    
		strcpy_s(m_name, name);
		m_CI = CI;
	}

}
void Plorg::changeCI(int CI)
{
    
    
	m_CI = CI;
}
void Plorg::show() const
{
    
    
	cout << "CI:" << m_CI << "\tname:" << m_name << endl;
}
int main()
{
    
    
	
	Plorg p1, p2 {
    
    "mfdsfasfdasdfasdfasdfasdfasdfasdfase",100 };
	p1.show();
	p1.changeCI(32);
	system("pause");
	/*
	const char* a = "fsdfsadfas";
	cout << strlen (a) << endl;
	cout << strlen("asfdfasdfasdf") << endl;
	system("pause");*/
}
  • 杂记:在类的函数范围内,如果传入同类的其他对象,那么私有的成员变量和函数也是可以访问的,如果传入其他类的对象,只能访问公有的数据和函数。

猜你喜欢

转载自blog.csdn.net/o_ogou/article/details/85329323