崔毅东 C++程序设计入门(上) 第4单元:物以类聚 – 对象和类 笔记

第1节:类的概念

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述

第2节:创建对象并访问对象成员

在这里插入图片描述在这里插入图片描述
问题:构造函数为什么不能有返回值?
答: 其实是有返回值的,返回this
不过 如果返回值会引起歧义,举个例子:
有个类是这个样子的:
class Test{
public:
int i;
int Test():i(0) { return 1;}
};
如果允许上面的定义成立,则会在下面的调用过程中产生矛盾。
调用过程:
Test t = Test();
1、这个是很普通的表达式,计算过程是从右边往左进行;
2、先看Test(),它会去调用类定义中的int Test():i(0) { return 1; }函数,并且生产一个临时的对象,姑且称呼为temp对象,temp对象的内部数据成员“i”的值是0;
3、与此同时,Test()返回了int型数据1;
4、此时,对象t就犯了难,到底是用int型数据1来对我进行初始化,还是用临时对象temp来对我进行初始化呢?
所以造成了歧义
(by m15522962525 superwukon)

第3节:关于创建对象的更多细节

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
struct中,如果不指明成员的访问控制属性,则默认的访问控制属性是:public
class中,如果不指明成员的访问控制属性,则默认的访问控制属性是:private

第4节:将声明与实现分离

在这里插入图片描述
在这里插入图片描述
Circle.h

class Circle{
public:
	double radius;
	Circle();
	Circle(double);
	double getArea();
};

Circle.cpp

#include "Circle.h"
Circle::Circle() {
	radius = 1;
}
Circle::Circle(double newRadius) {
	radius = newRadius;
}

double Circle::getArea() {
	return radius * radius * 3.14159;
}

TestCircleWithDeclaration.cpp

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

int main() {
  Circle circle1;
  Circle circle2(5.0);

  cout << "The area of the circle of radius " <<
          circle1.radius << " is " << circle1.getArea() << endl;
  cout << "The area of the circle of radius " <<
          circle2.radius << " is " << circle2.getArea() << endl;

  // Modify circle radius
  circle2.radius = 100;
  cout << "The area of the circle of radius " <<
          circle2.radius << " is " << circle2.getArea() << endl;

  return 0;
}

在这里插入图片描述
问题:U04S04-有没有办法判断函数是否被编译器内联?
答:用 attribute((always_inline))强制内联
attribute((noinline)) 强制不内联(by 黑猫VC 1064780263)

第5节:对象指针与动态对象

在这里插入图片描述在这里插入图片描述
问题 1 :
Circle circles[5];
Circle* p = circles;
你有多少种方法,可以调用circles数组中第0号对象的getArea函数呢?
答:circles[0].getArea()

(*circles).getArea()

circles->getArea();

(&circles[0])->getArea();

p->getArea();

(p+0)->getArea();

*p.getArea();

(&p[0])->getArea();

p[0].getArea();

问题 2 :(这是“奇技淫巧”,很可能你编一辈子程序也不会遇到)

void (*(*papf)[2])(int);

这个papf是什么东西(摘自C++ Primer)?
答:(*papf)[2] papf是一个指针,它指向一个数组,这个数组有两个元素
*(*papf)[2] papf是一个指针,它指向一个数组,这个数组有两个元素,且都是指针
*(*papf)[2]() papf是一个指针,它指向一个数组,这个数组有两个元素,且都是函数指针,
*(*papf)[2](int) 并且此函数拥有一个int参数,
void *(*papf)[2](int); ,无返回值
(by LengXAC)

第6节:C++字符串类

在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

第7节:数据域封装

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
Circle2.h

// radius --> private
// getter/setter 
class Circle
{
public:
  Circle();
  Circle(double);
  double getArea();
  double getRadius();
  void setRadius(double);

private:
  double radius_;
};

Circle2.cpp

#include "Circle2.h"

// Construct a circle object
Circle::Circle()
{
  radius_ = 1;
}

// Construct a circle object
Circle::Circle(double newRadius)
{
  radius_ = newRadius;
}

// Return the area of this circle
double Circle::getArea()
{
  return radius_ * radius_ * 3.14159;
}

// Return the radius of this circle
double Circle::getRadius()
{
  return radius_;
}

// Set a new radius
void Circle::setRadius(double newRadius)
{
  radius_ = (newRadius >= 0) ? newRadius : 0;
}

第8节:变量作用域与this指针

在这里插入图片描述在这里插入图片描述在这里插入图片描述
HideDataField.cpp

#include <iostream>
using namespace std;

class Foo
{
  public:
  int x; // data field
  int y; // data field

  Foo()
  {
    x = 10;
    y = 10;
  }

  void p()
  {
    int x = 20; // local variable
    cout << "x is " << x << endl;
    cout << "y is " << y << endl;
  }
};

int main()
{
  Foo foo;
  foo.p();

  return 0;
}

在这里插入图片描述在这里插入图片描述在这里插入图片描述
问题 :

当初设计C++语言时,为什么要有this指针?没有它行不行?
答:当参数名与数据域成员名相同时,而private的变量名后没有下划线,容易与参数的名字混淆。所以用this指针明确所属。this指针等于该类对象的地址,在对象内,函数非常难获得本对象的地址,所以,this指针还是很有必要的。
(by 侯云锋 已知黄昏晚)

第9节:对象作为函数参数

在这里插入图片描述
PassObjectToPointer.cpp

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

void printCircle(Circle *c) {
  cout << "The area of the circle of " << 
          c->getRadius() << " is " << c->getArea() << endl;
}

int main() {
  Circle myCircle(5.0);
  printCircle(&myCircle);

  return 0;
}

PassObjectByValue.cpp

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

void printCircle(Circle c) {
  cout << "The area of the circle of " <<
          c.getRadius() << " is " << c.getArea() << endl;
}

int main() {
  Circle myCircle(5.0);
  printCircle(myCircle);

  return 0;
}

PassObjectByReference.cpp

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

void printCircle(Circle &c) {
  cout << "The area of the circle of " <<
          c.getRadius() << " is " << c.getArea() << endl;
}

int main() {
  Circle myCircle(5.0);
  printCircle(myCircle);

  return 0;
}

问题:在为函数传参时, 何时用引用,何时用指针呢?
答:一般来说,能用引用尽量不用指针。引用更加直观,更少出现意外的疏忽导致的错误。
指针可以有二重、三重之分,比引用更加灵活。有些情况下,例如使用 new 运算符,只能用指针。
指针和引用的区别

第10节:对象数组

在这里插入图片描述
TotalArea.cpp

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

// Add circle areas
double sum(Circle circleArray[], int size) 
{
  // Initialize sum
  double sum = 0;

  // Add areas to sum
  for (int i = 0; i < size; i++)
    sum += circleArray[i].getArea();

  return sum;
}

// Print an array of circles and their total area
void printCircleArray(Circle circleArray[], int size)
{
  cout << "Radius\t\t" << "Area" << endl;
  for (int i = 0; i < size; i++)
  {
    cout << circleArray[i].getRadius() << "\t\t" <<
      circleArray[i].getArea() << endl;
  }

  cout << "-----------------------------------------" << endl;

  // Compute and display the result
  cout << "The total areas of circles is \t" <<
    sum(circleArray, size) << endl;
}

int main()
{
  const int SIZE = 10;

  // Create a Circle object with radius 1
  Circle circleArray[SIZE];

  for (int i = 0; i < SIZE; i++)
  {
    circleArray[i].setRadius(i + 1);
  }

  printCircleArray(circleArray, SIZE);

  return 0;
}

在这里插入图片描述

第11节:类抽象与封装

在这里插入图片描述
在这里插入图片描述

第12节:构造函数初始化列表

在这里插入图片描述在这里插入图片描述在这里插入图片描述
NoDefaultConstructor1.cpp

class Time
{
public:
  Time(int hour, int minute, int second)
  {
     // Code omitted
  }

private:
  int hour;
  int minute;
  int second;
};

class Action
{
public:
  Action(int hour, int minute, int second)
  {
    time = Time(hour, minute, second);
  }

private:
  Time time;
};

int main() {
    return 0;
}

无法编译通过
相关代码修改为

Action(int hour, int minute, int second) 
: time(hour, minute, second)
{
}

猜你喜欢

转载自blog.csdn.net/dldldl1994/article/details/86701480
今日推荐