note on cpp

//guard 防卫式声明,在cpp中不需要按顺序include,避免重复include
#ifndef __COMPLEX__
#define __COMPLEX__
...
#endif
    
    
//class template
//inline function  macro
template<typename T>
class complex
{
public:
    complex(double r=0,double i=0):re(r),im(i){}//initial list
    complex():re(0),im(0){}//overloading重载,但是上一行已经有默认参数,所以不可以有无参的重载
    
    //return by reference
    complex& operator +=(const comlpex&);
    
    //const member functions,不改变成员变量
    //定义时,const complex c(1,2)会出错
    double real() const {return re;} 
    double imag() const {return im;} //函数在class body内定义,自动转换为inline函数
    //不带指针的函数多半不用析构 string equal to *char[]
    
    //相同class的各个对象互为友元
    int func(const complex& param)
    {return param.re + param.im;}
private:
    T re, im;
    //构造函数放在private区和单例模式有关
    
    //友元函数可以自由访问我的private成员
    friend comlpex& __doapl (complex*, const complex&);
};

//how to use template
complex<double > c1(2.5, 3.5);
complex<int > c2(1, 2);

//参数传递:按值传递(pass by value)、引用传递(pass by reference to const)
//按值传递,整包传过去,东西太大,不适合
//reference(指针),给地址、速度快,尽量传引用,如果传过去怕被改就加const

//返回值传递也尽量按引用返回
//& * 返回value,接收是&?
//传递者无需知道接受者是以reference形式接收
inline complex& __doapl(complex* ths, const complex& r)
{
    ths->re += r.re;
    ths->im += r.im;
    return *ths;
}

//操作符重载-1,成员函数
inline complex& complex::operator += (const complex& r)
{
    //谁调用了这个函数,谁就是这个this,他在参数列表里,但是不能写出来
    return __doapl(this, r);
}

//操作符重载-2,非成员函数,与上述不同在于下面的么有this
//并且他们只能按值返回return by value,因为是局部对象,函数作用域结束后对象就消失,空引用
//complex + complex
inline complex operator + (const complex& x, const complex& y)
{
    return complex(real(x)+real(y),
                  imag(x)+imag(y));
}
//double+complex and complex+double
inline complex operator + (const complex& x,double y)
{
    return complex(real(x)+y,imag(x));
}
inline complex operator+(const complex& x){return x;}//参数只有一个,正号
//negate取反,产生新结果,创建新对象
inline complex operator-(const complex& x)
{	
    //local object
    //类名():临时对象
    return complex(-real(x), -imag(x));
}
//关于<<,cout可能并不认识后面的东西,并不能像int、char这些基本类型去输出
//写成成员函数,被作用的对象就变成了类,导致cout变右边:c1.re()<<cout;不好
//这也是这里写成全局函数而非成员函数的原因
//共轭复数
//重载操作符必须写成全局的原因?????
inline complex conj(const complex& x)
{
    return complex(real(x),-imag(x));
}
ostream& operator << (ostream& os, const complex& x)
{
    return os<<'('<<real(x)<<','<<imag(x)<<')';
}
/*
cout<<conj(c1);
cout<<c1<<conj(c1);
*/

总结:

1.数据放在private。

2.参数尽可能的按引用传递。(传过去不想被改就加const)

3.返回值同上。

4.初始化列表。

有些重载操作符必须写成全局的原因?????

因为在全局中才能传参,完成复数+实数的一些操作,否则写在类中只能完成复数+复数。

class with pointer member

#ifndef __MYSTRING__
#define __MYSTRING__
...
#endif

//class带指针,一定要有拷贝构造、拷贝赋值
//若没有写,就会按位(bit)复制,不好。bit copy
//
class String
{
public:
    String(const char* cstr = 0);
    //拷贝构造
    String(const String& str);
    //拷贝赋值
    String& operator = (const String& str);
    //析构
    ~String();
    char* get_c_str() const {return m_data;}
private:    
    //string = char*,动长,在不确定大小的情况下
    char* m_data;//只有4个字节,指针的大小就是一个地址的长度
}
//default ctor,string is a pointer,passed into a pointer
inline String::String(const char* cstr = 0){
    if(sctr){
        //this 2 line is copy ctor,passed into must be a object,param & 
        m_data=new char[strlen(csrt)+1];
        strcpy(m_data,cstr);
    }else{
		m_data=new char[1];
        *m_data='\n';
    }
}
//有动态分配的内存,要[]删除掉
inline String::~String(){
    delete[] m_data;
}

int main(){
	String s1();
	String s2("hello");
	String s3(s1);
	cout<<s3<<endl;
	s3=s2;
	cout<<s3<<endl;
    
    //
    String* p = new String("hello");
    delete p;
}

为什么有指针成员的类一定要有拷贝构造、拷贝赋值?

/*关于拷贝构造*/
String a("hello");
String b("world");
b=a;//这是浅拷贝
//a、b指向相同内容,原本b指向那块变成孤儿,导致memory leak
//修改a,b也会改变,当a析构后,b指向内容空,再去访问b的内容时,出错
//避免这种浅拷贝带来的不利,以下拷贝构造属于深拷贝
inline String::String(const String& str){
    m_data=new char[strlen(str.m_data) + 1];//兄弟之间互为友元
    strcpy(m_data, str.m_data);
}

{
    String s1("hello");
    String s2(s1);//以s1为蓝本创造一个新的给s2
    //String s2=s1;
}

在这里插入图片描述

/*关于拷贝赋值*/
//虽然返回的是this指针,当进行连续赋值的时候,不能把返回类型设为空
inline String& String::operator=(const String& str){
    //一定要检测自我赋值,否则一旦发生自我赋值时,程序会报错
    if(this == &str)
        return *this;
    //被赋值一方先清空自己
    delete[] m_data;
    //创建一个和对象一样大的空间
    m_data = new char[strlen(str.m_data)+1];
    //把对象复制进来
    strcpy(m_data,str.m_data);
    return *this;
}

{
    s2 = s1;//s1赋值给s2,this指向s2,
}
ostream& operator<<(ostream& os, const String& str){
    os<< str.get_c_str();
    return os;
}
{
    cout<<s1;
}

Stack,存在于某作用域的一块内存空间。例如调用函数时,函数本身会形成一个栈用来保存他接收的参数,以及返回的地址。在函数体内声明的任何变量,使用的内存块都来自栈。

Heap,由操作系统提供的一块全局内存空间,程序动态分配从中获得若干区域。

/*堆、栈与内存管理*/
class Complex{...};
...
//全局对象,直到程序结束
Complex c3(1,2)
int main()
{
	//c1占用的空间来自栈,auto object = local object会被自动清理
	Complex c1(1,2);
    //Complex(3)属于临时对象,其占用空间从堆中new得,并由p指向
	Complex* p = new Complex(3);//new了就要delete
    //static object在作用域结束后依然存在,直到整个程序结束
    static Complex c2(1,2);
    delete p;//没有的话会造成内存泄漏,本来有块内存,在某处失去了对这块内存的控制,无法delete还给操作系统,有限的内存。一旦离开这个作用域,这个指针就死亡了,但是它指向的内存空间没有释放,这就是内存泄漏。
}

news:先分配内存,在调用构造函数
Complex* p = new Complex(1,2);
==
//内部调用malloc(n)
void *mem=operator new(sizeof(Complex))//分配内存
pc = static_cast<Complex*> (mem);//转型
//Complex::Complex(pc, 1, 2);this指针指向pc
pc->Complex::Complex(1,2);//调用构造函数

delete:先调用析构,在释放内存  
delete p;
==
String::~String(p);
//内部调用free(p)
operator delete(p);

//array new要搭配array delete,避免String[3]中只有第一块空间的动态分配内存被清空,而后面两块没有
//inline可以多写,效果依赖于编译器的决定

about static

//nice singleton
class A{
public:
    static A& getInstance();
    setup() {...}
private:
    A();
    A(const A& rhs);
    ...
};
A& A::getInstance(){
    //need than create
    static A a;
    return a;
}

function template

stone r1(2,3),r2(3,3),r3;
r3 = min(r1,r2);//编译器会对函数模板做argument deduction

template <class T>
inline const T& min(const T& a, const T& b){
    return b<a?b:a;
}

class stone{
public:
	stone(int w,int h,int we):_w(w),_h(h),_weight(we){}
    bool operator < (const stone& rhs) const{
        return _weight<rhs._weight;
    }
private:    
    int _w,_h,_weight;
}
内容概要:本文档主要介绍了Intel Edge Peak (EP) 解决方案,涵盖从零到边缘高峰的软件配置和服务管理。EP解决方案旨在简化客户的入门门槛,提供一系列工具和服务,包括Edge Software Provisioner (ESP),用于构建和缓存操作系统镜像和软件栈;Device Management System (DMS),用于远程集群或本地集群管理;以及Autonomous Clustering for the Edge (ACE),用于自动化边缘集群的创建和管理。文档详细描述了从软件发布、设备制造、运输、安装到最终设备激活的全过程,并强调了在不同应用场景(如公共设施、工业厂房、海上油井和移动医院)下的具体部署步骤和技术细节。此外,文档还探讨了安全设备注册(FDO)、集群管理、密钥轮换和备份等关键操作。 适合人群:具备一定IT基础设施和边缘计算基础知识的技术人员,特别是负责边缘设备部署和管理的系统集成商和运维人员。 使用场景及目标:①帮助系统集成商和客户简化边缘设备的初始配置和后续管理;②确保设备在不同网络环境下的安全启动和注册;③支持大规模边缘设备的自动化集群管理和应用程序编排;④提供详细的密钥管理和集群维护指南,确保系统的长期稳定运行。 其他说明:本文档是详细描述了Edge Peak技术及其应用案例。文档不仅提供了技术实现的指导,还涵盖了策略配置、安全性和扩展性的考虑,帮助用户全面理解和实施Intel的边缘计算解决方案。
a.cpp:35:5: error: extra qualification ‘Stud::’ on member ‘sum’ [-fpermissive] 35 | int Stud::sum=0; | ^~~~ a.cpp:35:15: error: ‘int Stud::sum’ conflicts with a previous declaration 35 | int Stud::sum=0; | ^ a.cpp:15:19: note: previous declaration ‘double Stud::sum’ 15 | static double sum; | ^~~ a.cpp:36:5: error: extra qualification ‘Stud::’ on member ‘num’ [-fpermissive] 36 | int Stud::num=0; | ^~~~ a.cpp:45:2: error: expected ‘}’ at end of input 45 | } | ^ a.cpp:9:12: note: to match this ‘{’ 9 | class Stud { | ^ a.cpp: In member function ‘void Stud::print()’: a.cpp:28:24: error: expected primary-expression before ‘,’ token 28 | cout <<number<<, name<<, score<< endl; | ^ a.cpp:28:32: error: expected primary-expression before ‘,’ token 28 | cout <<number<<, name<<, score<< endl; | ^ a.cpp:28:39: error: invalid operands of types ‘float’ and ‘<unresolved overloaded function type>’ to binary ‘operator<<’ 28 | cout <<number<<, name<<, score<< endl; | ~~~~~^~~~~~~ a.cpp: In member function ‘int Stud::main()’: a.cpp:40:8: error: ‘class Stud’ has no member named ‘disp’ 40 | s1.disp(); | ^~~~ a.cpp:41:8: error: ‘class Stud’ has no member named ‘disp’ 41 | s2.disp(); | ^~~~ a.cpp:42:8: error: ‘class Stud’ has no member named ‘disp’ 42 | s3.disp(); | ^~~~ a.cpp:43:25: error: ‘avg’ is not a member of ‘Stud’ 43 | cout<<"avg="<<Stud::avg()<<endl; | ^~~ a.cpp: At global scope: a.cpp:45:2: error: expected unqualified-id at end of input 45 | } | ^
04-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值