本文主要是介绍C++工程笔记(配合SDUST OJ食用),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
使用了using namespace std; 仍然可以写std::cout
析构函数会在生命结束时自动调用
类内指针当作数组使用时需要先new分配内存
有关联的类可以加上友元 操作起来更加方便 T1779
输出构造、析构消息的题目一点内存都不能多开 否则会输出冗余信息
需要返回一个对象时可以先定义一个对象 并在类内写上无参构造函数T1829
先开空间再赋值T1784
定义在类内的数组需要先清空再使用 否则会有垃圾值T1816
注意const(只读) 与 &的使用
Eg.
设置Point对象的x坐标(第一个参数)和y坐标(第二个参数)并返回本对象:T1125
Point &setPoint(double x, double y)
{
a = x, b = y;
return *this;
}
const类型的变量在调用成员函数时要在参数名之后加上const(常对象只能调常函数)
Eg.
const Point const_point(3, 3);
const_point.show();
for(int i = 0; i <= l; i++)
{
if(const_point.isEqual(pt[i]))
{
ShowPoint(const_point);
ShowPoint(const_point.x(), const_point.y());
ShowPoint(Point(const_point.x(), const_point.y()));
}
bool isEqual(const Point &p)const
{
if(p.a == a && p.b == b)
return true;
else return false;
}
在初始化对象时尽量使用初始化列表:效率更高且可行性更高
写&不会开辟新的空间 如果不写可能会建立新的对象
类如何开数组?
写一个无参函数 例如:
Line():p1(0, 0), p2(0, 0) {}
重载流运算符需要注意的点:1.返回值类型 2.参数类型 3.输入输出流 4.返回值
friend istream& operator>>(istream& is, Time& rhs)
{
is >> rhs.hh >> rhs.mm >> rhs.ss; //要注入具体成员
return is;
}
friend ostream& operator<<(ostream& os, const Time& rhs)
{
if(rhs.hh < 0 || rhs.hh >= 24 || rhs.mm < 0 || rhs.mm >= 60 || rhs.ss < 0 || rhs.ss >= 60)
os << "error!!!";
else
os << setw(2) << setfill('0') << rhs.hh;
return os;
}
前自增与后自增(减法同理):
Time& operator++()
{
if(!is_leagal()) {}
else
{
ss ++;
while(ss >= 60) ss -= 60, mm ++;
while(mm >= 60) mm -= 60, hh ++;
hh = (hh + 24) % 24;
}
return *this;
}
Time operator++(int) //这里要加int
{
Time t(*this);
if(!is_leagal()) {}
else
{
ss ++;
while(ss >= 60) ss -= 60, mm ++;
while(mm >= 60) mm -= 60, hh ++;
hh = (hh + 24) % 24;
}
return t; //注意这里后自增要返回初始拷贝的对象
}
在传递字符串类中的字符参数时也要记得初始化其他对象
Eg.
private:
char* str;
int len;
public:
STR():str(NULL), len(0) {}
STR(const char* _str):len(0)
{
for(int i = 0; _str[i] != '\0'; i++)
len++;
str = new char[len + 1];
for(int i = 0; _str[i] != '\0'; i++)
str[i] = _str[i];
str[len] = '\0';
}
在类中带指针的成员一般需要进行动态内存分配 否则容易出错
delete数组要加[]
静态成员调用一定要用const
在写一个类的函数类模板时,记得写上public(class默认成员为private)
在类外调用类中某一成员函数时必须为静态成员函数
如:
类外:cout<<Point::showNumber()
类内:static int showNumber() {return num2;}
否则需要实例化,即:利用类定义一个对象,然后再调用成员函数
T1814用子类初始化父类
Derived(const Derived& d):x_(d.x_), Base(d) {cout << "Derived = " << x_ << " is copied." << endl;}
多继承:先继承,后组合
子类对象中包含父类子对象:里氏替换原则
纯虚函数不能实例化(定义对象): virtual void show()const = 0;
但是可以定义它的指针
//虚继承
#include <iostream>
using namespace std;
class A
{
public:
int a;
A(int aa):a(aa) {}
};
class B : virtual public A
{
public:
int b;
B(int aa, int bb):A(aa), b(bb) {}
};
class C : virtual public A
{
public:
int c;
C(int aa, int cc):A(aa), c(cc) {}
};
class D : public B, public C
{
public:
int d;
D(int x, int y, int z, int r):d(r), A(x), B(-1, y), C(-10086, z) {}
}; //此处初始化无效
int main()
{
D ddd(1, 2, 3, 4);
cout << ddd.d << endl;
cout << ddd.c << endl;
cout << ddd.b << endl;
cout << ddd.a << endl;
cout << ddd.A::a << endl;
cout << ddd.B::a << endl;
cout << ddd.C::a << endl;
cout << ddd.D::a << endl;
return 0;
}
最终只有一个a
// 虚函数
#include <iostream>
using namespace std;
class A
{
public:
int a;
A(int aa):a(aa) {}
virtual void show() {cout << a << endl;}
};
class B : public A
{
public:
int b;
B(int aa, int bb):A(aa), b(bb) {}
void show() {cout << a << ' ' << b << endl;}
};
class C : public A
{
public:
int c;
C(int aa, int cc):A(aa), c(cc) {}
void show() {cout << a << ' ' << c << endl;}
};
class D : public A
{
public:
int d;
D(int aa, int cc):A(aa), d(cc) {}
void show() {cout << a << ' ' << d << endl;}
};
/*
class D : public B, public C
{
public:
int d;
D(int x, int y, int z, int r):d(r), A(x), B(-1, y), C(-10086, z) {}
}; */
int main()
{
A* p[5];
B b(1, 2);
C c(10, 20);
D d(-1, -2);
A a(1000000);
C cc(77, 77);
p[0] = &a;
p[1] = &b;
p[2] = &c;
p[3] = &cc;
p[4] = &d;
for(int i = 0; i < 5; i ++)
p[i]->show();
return 0;
}
虚析构函数才能访问子类的虚构函数,并且能够防止内存泄漏
子类和父类关系是可以套很多层的:eg.
class Graphic
{
public:
virtual void show() = 0;
};
class Shape : public Graphic
{
public:
virtual void show() = 0;
};
class Solid : public Graphic
{
public:
virtual void show() = 0;
};
class Square : public Shape
{
private:
double a_;
public:
Square(double a):a_(a) {}
void show() {cout << "Square, side:" << a_ << ", area:" << a_ * a_ <<'.' << endl;}
};
Problem1680学到的:
如果数组模板类不好写 我们不妨直接使用vector
Fract& operator+=(Fract rhs)
{
if(cnt_ & 1) m_ = -m_;
if(rhs.cnt_ & 1) rhs.m_ = -rhs.m_;
int val = lcm(m_, rhs.m_);
int x1 = val / m_, x2 = val / rhs.m_;
z_ *= x1, rhs.z_ *= x2;
Fract fract(z_ + rhs.z_, val);
return *this = fract;
}
重载+=要传引用 不方便写时可采用最后两句,先构造再赋值返回
重载流输入的过程中可以做其他事情
friend istream& operator>>(istream& is, Fract& f)
{
int z, m;
is >> z >> m;
f = Fract(z, m);
return is;
}
直接构造更加顺畅
重载强制类型转换
operator double()
{
return (double)z_ / m_;
}
对子类成员初始化要用子类构造函数
T2310在重载下标运算符时他需要有一个返回的其他类的对象 并且要传回此类的引用才能修改其自身属性
这篇关于C++工程笔记(配合SDUST OJ食用)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!