面向对象程序设计及C++_MOOC练习(1)
适用对象: 参加南京邮电大学的C++课程的学生
声明: 本指南仅用于参考,以及追求更好的编程经验。如果涉及抄袭等问题,按照校规后果自负。
例1:I/O流
#include<iostream>
using namespace std;
int main()
{
double radius;
const double pi =3.14159;
cin>>radius;
if(redius<=0)
{
cout<<"error input!"<<endl;
}
else
{
double circumference = 2*pi*radius;
double area = pi*radius*radius;
cout<<area<<" "<<circumference<<endl;
}
return 0;
}
Q:我们是否还能再进一步改进?
A(deepseek-R1):
#include<iostream> using namespace std; int main() { double radius; const double pi = 3.14159; cin >> radius; if (radius > 0) { double area = pi * radius * radius; double circumference = 2 * pi * radius; cout << area << " " << circumference << endl; } else { cout << "error input!" << endl; } return 0; }
例二:动态内存管理
#include<iostream>
using namespace std;
//求整数的平均值和负数的个数
int main()
{
int n =0;
cin>>n;
int *p = new int[n];//生成指定数量的动态数组
double ave = 0,sum=0;
int pos=0,number=0;
for(int i=0;i!=n;++i)
{
cin>>p[i];
if(p[i]>0)
{
++pos;
sum+=p[i];
}
if(p[i]<0)
{
++number; //统计负数的个数
}
}
if(!pos)
{
ave =0;
}
else
{
ave=sum/pos;
}
cout << "ave=" <<ave<<" number="<<number<<endl;
delete []p;
return 0;
}
补充的测试样例:
输入:0;返回:ave=0, number=0
Q:我们是否还能再进一步改进?
A(qwen):
#include <iostream> using namespace std; // 函数声明 void readArray(int* arr, int n); double calculatePositiveAverage(const int* arr, int n, int& positiveCount); int countNegatives(const int* arr, int n); int main() { int n; cout << "请输入数组元素个数: "; cin >> n; // 动态分配数组 int* p = new int[n]; // 输入数组元素 readArray(p, n); // 计算正数平均值和统计负数个数 int positiveCount = 0; double ave = calculatePositiveAverage(p, n, positiveCount); int number = countNegatives(p, n); // 输出结果 cout << "ave=" << ave << " number=" << number << endl; // 释放动态分配的内存 delete[] p; return 0; } /** * 从标准输入读取数组元素 */ void readArray(int* arr, int n) { for (int i = 0; i < n; ++i) { cout << "请输入第" << i + 1 << "个元素: "; cin >> arr[i]; } } /** * 计算正数的平均值,并通过引用返回正数的数量 */ double calculatePositiveAverage(const int* arr, int n, int& positiveCount) { positiveCount = 0; double sum = 0.0; for (int i = 0; i < n; ++i) { if (arr[i] > 0) { sum += arr[i]; ++positiveCount; } } if (positiveCount == 0) { return 0.0; } else { return sum / positiveCount; } } /** * 统计负数的个数 */ int countNegatives(const int* arr, int n) { int count = 0; for (int i = 0; i < n; ++i) { if (arr[i] < 0) { ++count; } } return count; }
例三:练习类和对象数组的定义与使用,思考深拷贝与浅拷贝的问题
1
#include<iostream>
#include<string>
using namespace std;
class Student
{
private:
int age;
string name;
public:
Student(int m,string n);
Student();
~Student();
void SetMember(int m,string n);
int Getage();
string Getname();
};
Student::Student(int m,string n)
{
age=m;
name=n;
}
Student::Student()
{
age=0;
name="unnamed";
}
Student::~Student()
{
}
void Student::SetMember(int m,string n)
{
age=m;
name=n;
}
int Student::Getage()
{
// 返回年龄
return age;
}
string Student::Getname()
{
// 返回姓名
return name;
}
int main()
{
Student stu[3]={Student(13,"wang")};
stu[2].SetMember(12,"zhang");
for (int i =0;i!=3;++i)
{
cout<<stu[i].Getage()<<','<<stu[i].Getname()<<'\n';
}
return 0;
}
Q:我们是否有进一步改进的地方?
A:(QW-2.5)
#include<iostream> #include<string> using namespace std; class Student { private: int age; string name; public: // 构造函数 Student(int m = 0, const string& n = "unnamed") : age(m), name(n) {} // 设置成员变量 void SetMember(int m, const string& n) { age = m; name = n; } // 获取年龄 int GetAge() const { return age; } // 获取姓名 string GetName() const { return name; } }; int main() { // 在C++98中,数组元素不能直接使用构造函数初始化,所以我们逐个初始化 Student stu[3]; stu[0] = Student(13, "wang"); stu[1] = Student(); // 使用默认构造函数 stu[2] = Student(); stu[2].SetMember(12, "zhang"); // 输出学生信息 for (int i = 0; i < 3; ++i) { cout << stu[i].GetAge() << ',' << stu[i].GetName() << endl; } return 0; }
例四:练习类与对象的定义与正确使用
#include<iostream>
#include<string>
using namespace std;
class Car
{
private:
string brand;
string type;
int year;
double price;
public:
Car(string a="undefinition",string b="undefinition",int c=2000,double d=0);
string GetBrand();
string GetType();
int GetYear();
double GetPrice();
};
Car::Car(string a,string b,int c,double d):
brand(a),type(b),year(c),price(d)
{
}
string Car::GetBrand()
{
return brand;
}
string Car::GetType()
{
return type;
}
int Car::GetYear()
{
return year;
}
double Car::GetPrice()
{
return price;
}
int main()
{
Car car1("FIAT","Palio",2021,6.5);
cout<<car1.GetBrand()<<" "<<car1.GetType()<<" "<<car1.GetYear() <<" " <<car1.GetPrice()<<endl;
Car car2;
cout<<car2.GetBrand()<<" "<<car2.GetType()<<" "<<car2.GetYear()<<" " <<car2.GetPrice()<<endl;
return 0;
}
Q: 我们是否还有可以改进的地方
A: (deepseek)
#include <iostream> #include <string> using namespace std; class Car { private: string brand; string type; int year; double price; public: // 构造函数:参数使用 const 引用,默认值修正拼写错误 Car(const string& brand = "undefined", const string& type = "undefined", int year = 2000, double price = 0.0); // Getter 方法声明为 const,返回 const 引用避免拷贝 const string& GetBrand() const; const string& GetType() const; int GetYear() const; double GetPrice() const; // 添加输出运算符重载(可选优化) friend ostream& operator<<(ostream& os, const Car& car); }; // 成员初始化列表,参数命名更具描述性 Car::Car(const string& brand, const string& type, int year, double price) : brand(brand), type(type), year(year), price(price) {} // Getter 实现(const 修饰) const string& Car::GetBrand() const { return brand; } const string& Car::GetType() const { return type; } int Car::GetYear() const { return year; } double Car::GetPrice() const { return price; } // 输出运算符重载实现 ostream& operator<<(ostream& os, const Car& car) { os << car.GetBrand() << " " << car.GetType() << " " << car.GetYear() << " " << car.GetPrice(); return os; } int main() { Car car1("FIAT", "Palio", 2021, 6.5); cout << car1 << endl; // 使用运算符重载简化输出 Car car2; cout << car2 << endl; return 0; }
例五:使用对象成员构成新类
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
class Point
{
private:
double X, Y;
public:
Point( double a, double b );
Point( Point &p );
double GetX( ) ;
double GetY( ) ;
};
Point::Point(double a,double b):
X(a),Y(b)
{}
Point::Point(const Point &p):
X(p.X),Y(p.Y)
{}
double Point::GetX()
{
return X;
}
double Point::GetY()
{
return Y;
}
class Line
{
private:
Point A,B ; //定义两个Point类的对象成员
double length ;
public:
Line( Point p1 , Point p2 ) ;//Line类的构造函数原型,函数体类外实现
double GetLength( );
};
Line::Line(Point p1,Point p2):
A(p1),B(p2)
{
length=pow((pow((A.GetX()-B.GetX()),2)+pow((A.GetY()-B.GetY()),2)),0.5);
}
double Line::GetLength()
{
return length;
}
int main()
{
double a,b,c,d;
cin>>a>>b>>c>>d;
Point p1(a,b),p2(c,d);
Line L(p1,p2);
cout<<setprecision(3)<<L.GetLength()<<endl;
return 0;
}
Q: 我们是否还有可以改进的地方
A: (deepseek)
#include <iostream> #include <iomanip> #include <cmath> using namespace std; class Point { private: double X, Y; public: Point(double a, double b); Point(const Point& p); // 使用 const 引用 double GetX() const; // 添加 const 修饰符 double GetY() const; // 添加 const 修饰符 }; // 初始化列表直接初始化成员变量 Point::Point(double a, double b) : X(a), Y(b) {} // 拷贝构造函数参数改为 const 引用 Point::Point(const Point& p) : X(p.X), Y(p.Y) {} // Getter 方法声明为 const double Point::GetX() const { return X; } double Point::GetY() const { return Y; } class Line { private: const Point A, B; // 使用 const 成员避免拷贝 const double length; // 计算结果设为 const public: Line(const Point& p1, const Point& p2); // 参数改为 const 引用 double GetLength() const; // 方法声明为 const }; // 使用 std::hypot 优化距离计算,并在初始化列表中初始化所有成员 Line::Line(const Point& p1, const Point& p2) : A(p1), B(p2), length(hypot(p1.GetX() - p2.GetX(), p1.GetY() - p2.GetY())) {} // GetLength 返回 const 成员 double Line::GetLength() const { return length; } // main 函数保持不变 int main() { double a, b, c, d; cin >> a >> b >> c >> d; Point p1(a, b), p2(c, d); Line L(p1, p2); cout << setprecision(3) << L.GetLength() << endl; return 0; }
例六:静态成员的使用
#include<iostream>
#include<string>
using namespace std;
class Student
{
private:
int age;
string name;
public:
static int count;
Student(int m,string n);
Student();
void Print()const;
~Student();
};
int Student::count;
Student::Student(int m,string n):
age(m),name(n)
{
count++;
}
Student::Student():
age(0),name("NoName")
{
count++;
}
Student::~Student()
{
count--;
}
void Student::Print() const
{
static int a=0;
cout<<count-a<<endl;
cout<<"Name="<<name<<" , "<<"age="<<age<<endl;
}
int main()
{
cout << "count=" << Student::count << endl;
Student s1,*p = new Student( 23, "ZhangHong" ) ;
s1.Print( ) ;
p -> Print( ) ;
delete p;
s1.Print( ) ;
Student Stu[4];
cout << "count=" << Student::count << endl ;
return 0;
}
Q:我们是否还可以优化代码?
A:(deepseek)
#include <iostream> #include <string> using namespace std; class Student { private: int age; string name; public: static int count; Student(int m, const string& n); // 参数改为 const 引用 Student(); void Print() const; ~Student(); }; // 显式初始化静态成员 int Student::count = 0; // 使用成员初始化列表规范构造函数 Student::Student(int m, const string& n) : age(m), name(n) { ++count; // 使用前缀自增符(更符合现代C++风格) } Student::Student() : age(0), name("NoName") { ++count; } Student::~Student() { --count; } // 优化Print方法:移除冗余静态变量,规范输出格式 void Student::Print() const { cout << "Current count = " << count << endl; cout << "Name = " << name << ", Age = " << age << endl; } int main() { // 保持main函数完全不变 cout << "count=" << Student::count << endl; Student s1, *p = new Student(23, "ZhangHong"); s1.Print(); p->Print(); delete p; s1.Print(); Student Stu[4]; cout << "count=" << Student::count << endl; return 0; }
例七:由POINT类派生CIRCLE类,完成类的定义并验证
#include<iostream>
#include<string>
using namespace std;
class POINT
{
private:
int x,y;
public:
POINT(int a,int b);
void change(int a,int b);
void show();
};
POINT::POINT(int a,int b):
x(a),y(b)
{
}
void POINT::change(int a,int b)
{
x=a;
y=b;
}
void POINT::show()
{
cout<<"("<<x<<","<<y<<")"<<endl;
}
class CIRCLE:public POINT
{
private:
int r;
public:
CIRCLE(int a,int b,int c);
void show();
};
CIRCLE::CIRCLE(int a,int b,int c):
POINT(a,b),r(c)
{
}
void CIRCLE::show()
{
cout<<"the center of the circle is:\n";
POINT::show( );
cout<<"the radius is:"<<r<<endl;
}
int main()
{
POINT p (2, 3);
CIRCLE c (3, 4, 5);
cout<<"original p:\n";
p.show ();
p.change (20,30);
cout<<"changed p:\n";
p.show ();
cout<<"original c:\n";
c.show ( );
c.change (30,40);
cout<<"changed c:\n";
c.show ( );
return 0;
}
Q:我们的代码是否可以进行优化?
A:(deepseek)
#include <iostream> #include <string> using namespace std; class POINT { private: int x, y; public: POINT(int x, int y); // 参数命名更具描述性 void change(int x, int y); // 参数改为 const 引用(若允许修改参数类型) void show() const; // 声明为 const 方法 }; POINT::POINT(int x, int y) : x(x), y(y) {} void POINT::change(int x, int y) { this->x = x; this->y = y; } void POINT::show() const { cout << "(" << x << ", " << y << ")" << endl; // 优化输出格式 } class CIRCLE : public POINT { private: int r; public: CIRCLE(int x, int y, int r); // 参数命名统一 void show() const; // 声明为 const 方法 }; CIRCLE::CIRCLE(int x, int y, int r) : POINT(x, y), r(r) {} void CIRCLE::show() const { cout << "The center of the circle is:\n"; POINT::show(); // 调用基类方法 cout << "The radius is: " << r << endl; // 规范输出格式 } // main 函数保持不变 int main() { POINT p(2, 3); CIRCLE c(3, 4, 5); cout << "Original p:\n"; p.show(); p.change(20, 30); cout << "Changed p:\n"; p.show(); cout << "Original c:\n"; c.show(); c.change(30, 40); cout << "Changed c:\n"; c.show(); return 0; } ``