c++ 代码结构 and 古怪

1、h是class定义
cpp 是实现
带main的cpp是调用
2、调h里面的namespace里面的数据或者算法

古怪
1、this是对象的address,对象本身是 *this
2、括号中的const表明改函数不会修改被显式访问的对象;括号后的const表明,不会修改被隐式访问的对象,即 *this。因为返回了两个const对象之一的引用,因此返回类型也应为const引用

const Stock & Stock::topval(const Stock & s) const
{
  if(s.total_val >total_val)
    return s;
  else
    return *this;
}
total = coding.operator+(fixing);
//将方法命令为operator+()后,也可以使用运算符表示:
total = coding + fixing;
//先有上面的操作符简化的书写方式,然后引出问题头一个参数必须是对象
//引出解决方法---非成员函数访问类的私有成员,即为友元函数 friend
//作用是用在运算符重载的时候第一个参数不用必须是类对象了
//定义类特定的常量,if他们是整数,enum提供了一种方便的途径
enum {fck=14};
//当然can this way
static const int fck=14;
复制构造函数用于将一个对象复制到新创建的对象中。也包括按值传递参数和返回对象
//将对象作为函数参数按值传递的时候会调用对象的复制构造函数,所以析构函数会比构造函数多调用一次
//https://blog.csdn.net/yangkunqiankun/article/details/74885784
StringBad sailor = sports;//这使用的是哪个构造函数呢?不是默认的,也不是带参数你定义的
//上面的代码等同于
StringBad sailor = StringBad(sports);
//当你使用一个对象初始化另一个对象时,编译器将自动生成上述构造函数
//(即复制构造函数,因为它创建对象的一个副本)
//所有问题的罪魁祸首就是这种构造函数(编译器自动生成的成员函数)
浅复制:仅仅是指向被复制的内存地址,如果原地址发生改变,那么浅复制出来的对象也会相应的改变。 深复制:在计算机中开辟一块新的内存地址用于存放复制的对象
如果类中包含了使用new初始化的指针成员,应当定义一个复制构造函数
temp[0]=='\0';// empty line
Act *pt = new Act;
delete pt;  //delete释放的是保存pt指针的空间,析构函数释放的是pt指向的内存空间
析构函数的调用时机(p472)
1、如果对象是动态变量,则当执行完定义该对象的程序块时,调用析构
2、如果对象时静态变量,则在程序结束时调用
3new出来的,delete的时候调用
int &b=a;        //引用,注意传参的时候也是引用
int *p=&a;        //取地址
和类型在一起的是引用,和变量在一起的是取址

class A {...}  //声明一个 类 A
void *buf =  malloc(sizeof(A));   //简单地分配空间。
A *ojb = new (buf)A();    // 在分配的空间上调用构造函数。
//现在问题来了: 这里 的空间可以是任意的空间吗,答案是的! 
//这里的 “已经分配好的空间” 可以是任何的空间,比如说 可以是栈上的空间!
  class A {int a;}
  int buf[sizeof(A)];   //在栈上,分配一个数组
  A *obj =  new(buf) A();  //在这个数组上构造一个 对象 A。
-------------------------
定位new的格式为
new(args) T
其中,args是一个对象的指针,即指定的起始地址;T是分配内存的类型;返回值也是指定的起始地址。
char x[sizeof(MyClass)];
MyClass* fPtr2 = new(&x[0])MyClass;
通过定位new分配的内存就是在数组x的起始地址上。

 释放内存
由于定位new分配的内存并不是“新分配”的,而是原先就有的。所以不能使用delete来释放该内存,而是要通过析构函数来释放资源。
fPtr2->~MyClass();
//成员初始化列表 several 种语法
//类名和构造函数
TableTennis::TableTennis(const string & fn,bool ht):firstname(fn),hasTable(ht){}
TableTennis::TableTennis(const string & fn,bool ht)
{
  firstname=fn;
  hasTable=ht;
}

//derived class 派生类
派生类不能直接访问基类的私有数据,必须使用基类的共有方法才可以。构造函数使用一种技术,其他成员函数是另一种技术
1、派生类构造函数初始化基类私有数据时,采用的是成员初始化列表语法
RatedPlayer::RatedPlayer(unsigned int r,const string & fn,const string & ln,bool ht):TableTennisPlayer(fn,ln,ht)
{
  rating = r;
}

对于成员对象,构造函数则使用成员名
Student(const char * str, const double * pd, int n):name(str), scores(pd, n) {}
虚析构函数的重要性:
Brass是基类,BrassPlus是派生类
Brass *p_clients[5];
如果析构函数不是虚的,那么只调用Brass的析构函数,不调用BrassPlus.所以设成虚函数那么就会先调BrassPlus的析构函数,然后再是Brass的
//p541
//赋值运算符原型
Star & Star::operator=(const Star &);
赋值运算符函数返回一个Star对象引用。
编译器不会生成将一种类型赋给另一种类型的赋值运算符。如果希望能将字符串赋给Star对象,
Star & Star::operator=(const char *) {...}

转换函数

Star::Star double() {...} //converts star to double
//converts to const char
Star::Star const char * () {...}

// returns a Star object
Star nova1(const Star &);
// returns a reference to a Star
Star & noval2(const Star &);

直接返回对象一般用在返回临时对象,(参考按值传递和按引用传递,复制函数)
Vector Vector::operator+(const Vector & b) const
{
  return Vector(x + b.x, y + b.y);
}

// 确保方法不修改参数
Star::Star(const char * s) {...}
// 确保方法不修改调用它的对象
void Star::show() const {...}

// 确保返回值不被修改
const Stock & Stock::topval(const Stock & s) const

在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。
纯虚函数不在父类中实现,必须在子类中实现
纯虚函数只有定义,没有实现;而虚函数既有定义,也有实现的代码。
含有纯虚拟函数的类称为抽象类,包含纯虚函数的类不能定义其对象,而包含虚函数的则可以

void show(const Brass & rba)
{
  rba.ViewAcct();
}
void inadequate(Brass ba)
{
  ba.ViewAcct();
}

BrassPlus buzz("Buzz P",4300);
show(buzz);//因为是引用,所以buzz解释为BrassPlus版本
inadequate(buzz);//按值传递,只有buzz的Brass部分被显示
valarray是模板类  P552 《C++ Primer Plus》
声明对象语法 valarray<int> q_values; // an array of int
operator[]():让您能够访问各个元素

explicit用于防止构造函数隐式转换,比如给一个对象赋值int值,
编译器就会告诉你int不能隐式成这个对象
类模板就是可以将类型作为参数传递给这个类,产生一个类通用的作用
模板的作用就让程序员可以复用一些经过测试的代码
1、如果指向的对象(*pt)的类型为Type或者是从Type直接或间接派生而来的类型,
则下面的表达式将指针pt转换为Type类型的指针:
dynamic_cast<Type *>(pt)
否则,结果为0,即空指针

2、如果pg指向的是一个Magnificent对象,则下述表达式的结果为booltrue,否则为false:
typeid(Magnificent) == typeid(*pg)

智能指针模板的作用:自动释放动态内存。(auto_ptr, shared_ptr, unique_ptr)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值