实验2
#pragma once
#include<string>
//类T:声明
class T
{
//对象属性、方法
public:
T(int x = 0, int y = 0);//普通构造函数
T(const T& t);//复制构造函数
T(T &&t); //移动构造函数
~T();
void adjust(int ratio);//按系数成倍调整数据
void display() const; //以(m1,m2)形式显示T类对象信息
private:
int m1, m2;
//类属性、方法
public:
static int get_cnt();//显示当前T类对象总数
public:
static const std::string doc;//类T的描述信息
static const int max_cnt; //类T对象上限
private:
static int cnt; //当前T类对象数目
//类T友元函数声明
friend void func();
};
//普通函数声明
void func();
#include"T.h"
#include<iostream>
#include<string>
//类T实现
//static成员数据类初始化
const std::string T::doc{ "a simple class sample" };
const int T::max_cnt = 999;
int T::cnt = 0;
//类方法
int T::get_cnt() {
return cnt;
}
//对象方法
T::T(int x, int y) :m1{ x }, m2{ y } {
++cnt;
std::cout << "T constructor called.\n";
}
T::T(const T& t) :m1{ t.m1 }, m2{ t.m2 } {
++cnt;
std::cout << "T copy constructor called.\n";
}
T::T(T&& t) :m1{ t.m1 }, m2{ t.m2 }
{
++cnt;
std::cout << "T move constructor called.\n";
}
T::~T() {
--cnt;
std::cout << "T destructor called.\n";
}
void T::adjust(int ratio)
{
m1 *= ratio;
m2 *= ratio;
}
void T::display()const
{
std::cout << "(" << m1 << "," << m2 << ")";
}
//普通函数实现
void func()
{
T t5(42);
t5.m2 = 2049;
std::cout << "t5 = ";t5.display();std::cout << '\n';
}
#include "T.h"
#include<iostream>
void test_T();
int main()
{
std::cout << "test class T:\n";
test_T();
std::cout << "\ntest friend func: \n";
func();
}
void test_T()
{
using std::cout;
using std::endl;
cout << "T info: " << T::doc << endl;
cout << "T objects'max count: " << T::max_cnt << endl;
cout << "T objects'current count: " << T::get_cnt() << endl << endl;
T t1;
cout << "t1 = ";t1.display();cout << endl;
T t2(3, 4);
cout << "t2 = ";t2.display();cout << endl;
T t3(t2);
t3.adjust(2);
cout << "t3 = ";t3.display();cout << endl;
T t4(std::move(t2));
cout << "t4 = ";t4.display();cout << endl;
cout << "test: T objects'current count: " << T::get_cnt() << endl;
}
结果截图:

1:vs2022依然可以运行
2:普通构造函数:作用为初始化对象,调用时机是当对象不提供任何实参或提供整数实参时调用
拷贝构造函数:作用是用已存在的对象的成员值初始化新对象,调用时机为用一个对象初始化另一个新对象时
移动构造函数:作用为调用一个即将销毁的对象资源,调用时机为用一个临时对象初始化新对象时
析构函数:作用为清理资源,调用时机为作用域结束
3:vs2022可以运行
任务2
源代码
#pragma once
#include <string>
#include <cmath>
class Complex {
public:
Complex(double r = 0.0, double i = 0.0);
Complex(const Complex &c);
double get_real() const;
double get_imag() const;
void add(const Complex &c);
static const std::string doc;
private:
double real, imag;
friend void output(const Complex &c);
friend double abs(const Complex &c);
friend Complex add(const Complex &a, const Complex &b);
friend bool is_equal(const Complex &a, const Complex &b);
friend bool is_not_equal(const Complex &a, const Complex &b);
};
#include "Complex.h"
#include <iostream>
const std::string Complex::doc = "a simplified complex class";
Complex::Complex(double r, double i): real{r}, imag{i} {}
Complex::Complex(const Complex &c): real{c.real}, imag{c.imag} {}
double Complex::get_real() const { return real; }
double Complex::get_imag() const { return imag; }
void Complex::add(const Complex &c) {
real += c.real;
imag += c.imag;
}
void output(const Complex &c) {
std::cout << c.real << (c.imag >= 0 ? " + " : " - ")
<< std::abs(c.imag) << "i";
}
double abs(const Complex &c) {
return std::sqrt(c.real * c.real + c.imag * c.imag);
}
Complex add(const Complex &a, const Complex &b) {
return Complex(a.real + b.real, a.imag + b.imag);
}
bool is_equal(const Complex &a, const Complex &b) {
return a.real == b.real && a.imag == b.imag;
}
bool is_not_equal(const Complex &a, const Complex &b) {
return !(is_equal(a, b));
}
运行结果截图:

问题2:
1.需要,可以通过设置为friend实现
2.不是
3.将 Complex 类的拷贝构造函数声明为 explicit
任务3:
源码
#include"PlayerControl.h"
#include<iostream>
void test()
{
PlayerControl controller;
std::string control_str;
std::cout<<"Enter Control: (play/pause/next/prev/stop/quit):\n";
while(std::cin>>control_str)
{
if(control_str=="quit")
break;
ControlType cmd=controller.parase(control_str);
controller.execute(cmd);
std::cout<<"Current Player control: "<<PlayerControl::get_cnt()<<"\n\n";
}
}
int main()
{
test();
}
运行截图:

任务4:
源代码:
#pragma once
#include <string>
class Fraction {
public:
Fraction(int up = 0, int down = 1);
Fraction(const Fraction& f);
int get_up() const;
int get_down() const;
Fraction negative() const;
static const std::string doc;
private:
int up, down;
void simplify();
friend void output(const Fraction& f);
friend Fraction add(const Fraction& a, const Fraction& b);
friend Fraction sub(const Fraction& a, const Fraction& b);
friend Fraction mul(const Fraction& a, const Fraction& b);
friend Fraction div(const Fraction& a, const Fraction& b);
};
#include "Fraction.h"
#include <iostream>
#include <numeric>
#include <stdexcept>
const std::string Fraction::doc = "Fraction类 v0.01版";
Fraction::Fraction(int u, int d): up{u}, down{d} {
if (down == 0) throw std::invalid_argument("Denominator cannot be zero");
simplify();
}
Fraction::Fraction(const Fraction& f): up{f.up}, down{f.down} {}
void Fraction::simplify() {
if (down < 0) { down = -down; up = -up; }
int g = std::gcd(up, down);
if (g != 0) { up /= g; down /= g; }
}
int Fraction::get_up() const { return up; }
int Fraction::get_down() const { return down; }
Fraction Fraction::negative() const {
return Fraction(-up, down);
}
void output(const Fraction& f) {
std::cout << f.up << "/" << f.down;
}
Fraction add(const Fraction& a, const Fraction& b) {
return Fraction(a.up * b.down + b.up * a.down, a.down * b.down);
}
Fraction sub(const Fraction& a, const Fraction& b) {
return Fraction(a.up * b.down - b.up * a.down, a.down * b.down);
}
Fraction mul(const Fraction& a, const Fraction& b) {
return Fraction(a.up * b.up, a.down * b.down);
}
Fraction div(const Fraction& a, const Fraction& b) {
if (b.up == 0) throw std::invalid_argument("Division by zero");
return Fraction(a.up * b.down, a.down * b.up);
}
运行结果:

问题回答:
用友元函数因为它们彼此需要访问对方。

浙公网安备 33010602011771号