《C++ Primer Plus(第六版)》(30)(第十四章 C++中的代码重用 编程题答案)

14.7 编程练习

1.Wine类有一个string类对象成员(参见第4章)和一个Pair对象(参见本章):其中前者用来存储葡萄酒的名称,而后者有2个valarry<int>对象(参见本章),这两个valarry<int>对象分别保存了葡萄酒的酿造年份和该年生产的瓶数。例如,Pair的第1个valarray<int>对象可能为1988、1992和1996,第二个valarry<int> 对象可能为24、48和144瓶。Wine最好有1个int成员用于存储年数。另外,一些typedef可能有助于简化编程工作:

typedef std::valarry<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;
这样,PairArray表示的类型是Pair<std::valarry<int>,std::valarray<int>>。使用包含来实现Wine类,并用一个简单的程序对其进行测试。Wine类应该有一个默认构造函数以及如下的构造函数:

Wine(const char* l, int y, const int yr[], ocnst int bot[]);
Wine(const char* l, int y);
Wine类应该有一个GetBottles()方法,它根据Wine对象能够存储集中年份(y),提示用户输入年份和瓶数。方法Label()返回一个指向葡萄酒名称的引用。sum()方法返回Pair对象中第二个valarray<int>对象中的瓶数总和。

测试程序应提示用户输入葡萄酒名称、元素个数以及每个元素存储的年份和瓶数等信息。程序将使用这些数据来构造一个Wine对象,然后显示对象中保存的信息。

下面是一个简单的测试程序:

int main()
{
    cout << "Enter name of wine: ";
    char lab[50];
    cin.getline(lab, 50);
    cout << "Enter number of years: ";
    int yrs;
    cin >> yrs;
    
    Wine holding(lab, yrs);
    holding.GetBottles();
    holding.Show();
    
    const int YRS = 3;
    int y[YRS] = {1993, 1995, 1998};
    int b[YRS] = {48, 60, 72};
    Wine more("Gushing Grape  Red", YRS, y, b);
    more.Show();
    cout << "Total bottle for " << more.Label()
    <<": " << more.sum() << endl;
    cout << "Bye\n";
    
    return 0;
}
下面是该程序的运行情况:

Enter name of wine: Gully Wash

Enter number of years: 4

Enter Gully Wash data for 4 year(s):

Enter year: 1988

Enter bottles for that year: 42

Enter year: 1994

Enter bottles for that year: 58

Enter year: 1998

Enter bottles for that year: 122

Enter year: 2001

Enter bottles for that year: 144

Wine: Gully Wash

Year Bottles

1988 42

1994 58

1998 122

2001 144

Wine: Gushing Grape  Red

Year Bottles

1993 48

1995 60

1998 72

Total bottle for Gushing Grape  Red: 180

Bye

代码:

Test.h

//
//  Test.h
//  HelloWorld
//
//  Created by feiyin001 on 16/12/21.
//  Copyright (c) 2016年 FableGame. All rights reserved.
//

#ifndef _Test_H_
#define _Test_H_
#include <iostream>
#include <string>
#include <valarray>
using namespace std;
namespace FableGame
{

    typedef std::valarray<int> ArrayInt;
    typedef pair<ArrayInt, ArrayInt> PairArray;
    
    class Wine
    {
    private:
        string name;
        PairArray info;
        int yearNum;
    public:
        Wine(const char* l, int y, const int yr[], const int bot[]);
        Wine(const char* l, int y);
        void GetBottles();
        void Show();
        string& Label(){ return name;}
        int sum();
    };
}
#endif
Test.cpp

//
//  Test.cpp
//  HelloWorld
//
//  Created by feiyin001 on 16/12/21.
//  Copyright (c) 2016年 FableGame. All rights reserved.
//

#include "Test.h"
#include <iostream>
#include <cstdlib>
using namespace std;
using namespace FableGame;

Wine::Wine(const char* l, int y, const int yr[], const int bot[])
{
    name = l;
    yearNum = y;
    ArrayInt years(y);
    ArrayInt bots(y);
    
    for (int i = 0; i < y; ++i)
    {
        years[i] = yr[i];
        bots[i] = bot[i];
    }
    info = make_pair(years, bots);
}
Wine::Wine(const char* l, int y)
{
    name = l;
    yearNum = y;
}

void Wine::GetBottles()
{
    cout << "Enter " << name << " data for " << yearNum << " year(s):\n";
    info.first.resize(yearNum);
    info.second.resize(yearNum);
    for (int i = 0; i < yearNum; ++i)
    {
        cout << "Enter year: ";
        cin >> info.first[i];
        cout << "Enter bottles for that year: ";
        cin >> info.second[i];
    }
}
void Wine::Show()
{
    cout << "Wine: " << name << endl;
    cout << "\t\tYear\tBottles\n";
    for (int i = 0; i < yearNum; ++i)
    {
        cout << "\t\t" << info.first[i] << "\t" << info.second[i]<<endl;
    }
}
int Wine::sum()
{
    return info.second.sum();
}
这道题考验的是对于一些模板类的使用。以及has-a关系的应用。


2.采用私有继承而不是包含来完成编程练习1.同样,一些typedef可能会有所帮助,另外,您可能还需要考虑诸如下面这样的语句的含义:

PairArray::operator=(PairArray(ArrayInt(), ArrayInt()));
cout << (const string&)(*this);
您设计的类应该可以使用编程练习1中的测试程序进行测试。
//
//  Test.h
//  HelloWorld
//
//  Created by feiyin001 on 16/12/21.
//  Copyright (c) 2016年 FableGame. All rights reserved.
//

#ifndef _Test_H_
#define _Test_H_
#include <iostream>
#include <string>
#include <valarray>
using namespace std;
namespace FableGame
{

    typedef std::valarray<int> ArrayInt;
    typedef pair<ArrayInt, ArrayInt> PairArray;
    
    class Wine: private string, private PairArray
    {
    private:
        int yearNum;
    public:
        Wine(const char* l, int y, const int yr[], const int bot[]);
        Wine(const char* l, int y);
        void GetBottles();
        void Show();
        string& Label();
        int sum();
    };
}
#endif
Test.cpp

//
//  Test.cpp
//  HelloWorld
//
//  Created by feiyin001 on 16/12/21.
//  Copyright (c) 2016年 FableGame. All rights reserved.
//

#include "Test.h"
#include <iostream>
#include <cstdlib>
using namespace std;
using namespace FableGame;

Wine::Wine(const char* l, int y, const int yr[], const int bot[])
{
    (string&)(*this) = l;
    yearNum = y;
    ArrayInt years(y);
    ArrayInt bots(y);
    
    for (int i = 0; i < y; ++i)
    {
        years[i] = yr[i];
        bots[i] = bot[i];
    }
    (PairArray&)(*this) = make_pair(years, bots);
}
Wine::Wine(const char* l, int y)
{
    (string)(*this) = l;
    yearNum = y;
}

void Wine::GetBottles()
{
    cout << "Enter " << (const string&)(*this) << " data for " << yearNum << " year(s):\n";
    PairArray& info = (PairArray&)(*this);
    info.first.resize(yearNum);
    info.second.resize(yearNum);
    for (int i = 0; i < yearNum; ++i)
    {
        cout << "Enter year: ";
        cin >> info.first[i];
        cout << "Enter bottles for that year: ";
        cin >> info.second[i];
    }
}
string& Wine::Label()
{
    return (string&)(*this);
}
void Wine::Show()
{
    cout << "Wine: " << (const string&)(*this) << endl;
    cout << "\t\tYear\tBottles\n";
    PairArray& info = (PairArray&)(*this);
    for (int i = 0; i < yearNum; ++i)
    {
        cout << "\t\t" << info.first[i] << "\t" << info.second[i]<<endl;
    }
}
int Wine::sum()
{
    return ((PairArray&)(*this)).second.sum();
}
利用引用可以大幅减少修改的程度。


4.Person类保存人的名和姓。除构造函数外,它还有Show()方法,用于显示名和姓。Gunslmger类以Person类为虚基类派生而来,它包含一个Draw()成员,该方法返回一个double值,表示枪手的拔枪时间。这个类还包含一个int成员,表示枪手枪上的刻痕数。最后,这个类还包含一个Show()函数,用于显示所有这些信息。

PokerPlayer类以Person类为虚基类派生而来。它包含一个Draw()成员,该函数返回一个1~52的随机数,用于扑克牌的值(也可以用定义一个Card类,其中包含花色和面值成员,然后让Draw()返回一个Card对象)。PokerPlayer类使用Person类的show()函数。BadDude()类从Gunslinger何PokerPlayer类公有派生而来。它包含Gdraw()成员(返回坏蛋拔枪时间)和Cdraw()成员(返回下一张扑克牌),另外还有一个合适的show()函数。请定义这些类和方法以及其他必要的方法(如用于设置对象值的方法),并使用一些类似程序清单14.12的简单程序对它们进行测试。

Test.h

//
//  Test.h
//  HelloWorld
//
//  Created by feiyin001 on 16/12/21.
//  Copyright (c) 2016年 FableGame. All rights reserved.
//

#ifndef _Test_H_
#define _Test_H_
#include <iostream>
#include <string>
#include <valarray>
using namespace std;
namespace FableGame
{
    class Person
    {
    private:
        string surname;//姓
        string personalName;//名
        
    public:
        Person(){}
        Person(const string& s, const string& p)
        {
            surname = s;
            personalName = p;
        }
        virtual ~Person(){}
        virtual void set()
        {
            cout << "Enter surname: ";
            getline(cin, surname);
            cout << "Enter personal name: ";
            getline(cin, personalName);
        }
        virtual void show()
        {
            cout << personalName << " " << surname;
        }
    };
    
    class Gunslinger :public virtual Person
    {
    private:
        double gunTime;
        int gunNum;
        void setDate()
        {
            cout << "Enter gunTime: ";
            cin >> gunTime;
            cout << "Enter gunNum: ";
            cin >> gunNum;
            cin.get();
        }
    public:
        virtual ~Gunslinger(){}
        double draw(){ return gunTime;}
        virtual void show()
        {
            Person::show();
            cout << " " << gunTime << " " << gunNum;
        }
        virtual void set()
        {
            Person::set();
            setDate();
        }
    };
    
    class PokerPlayer: public virtual Person
    {
    public:
        int draw()
        {
            srand(time(0));
            return rand()%52 + 1;
        }
        virtual ~PokerPlayer(){}
    };
    
    class BadDude: public Gunslinger, public PokerPlayer
    {
    public:
        
        double gdraw()
        {
            return Gunslinger::draw();
        }
        int cdraw()
        {
            return PokerPlayer::draw();
        }
        void show()
        {
            Gunslinger::show();
        }
    };
}
#endif
main.cpp

//
//  main.cpp
//  HelloWorld
//
//  Created by feiyin001 on 16/12/21.
//  Copyright (c) 2016年 FableGame. All rights reserved.
//
#include <iostream>
#include "Test.h"
using namespace std;
using namespace FableGame;
const int ARRSIZE = 5;
int main()
{
    Person* person[ARRSIZE];
    int ct = 0;
    for (ct = 0; ct < ARRSIZE; ct++) {
        int choice;
        cout << "Enter the person category:\n"
            << "1: person 2:gunslinger"
            << "3: pokerplayer 4: BadDude 0:quit\n";
        cin >> choice;
        while (choice < 0 || choice > 4) {
            cout << "Please enter 1, 2, 3, 4 or 0: ";
            cin >> choice;
        }
        if (choice == 0) {
            break;
        }
        cin.get();
        switch (choice) {
            case 1:
                person[ct] = new Person;
                break;
            case 2:
                person[ct] = new Gunslinger;
                break;
            case 3:
                person[ct] = new PokerPlayer;
                break;
            case 4:
                person[ct] = new BadDude;
                break;
        } 
        person[ct]->set();
    }
    
    cout << "\nAll PersonL\n";
    for (int i = 0; i < ct; ++i) {
        cout << endl;
        person[i]->show();
    }
    for (int i = 0; i < ct; ++i) {
        delete person[i];
    }
    cout << "Bye.\n";
    return 0;
}

漏得最多的地方就是各个函数的virtual。导致读写和析构都出问题。

这道题主要检验多重继承的把握。关键是准确调用父类的函数,还有注意构造函数和析构函数。


5.下面是一些类声明:

	 class AbstrEmp
	 {
	 private:
		 string _fname;
		 string _lname;
		 string _job;
	 public:
		 AbstrEmp();
		 AbstrEmp(const std::string& fn, const string& ln, const string& j);
		 virtual void showAll()const;
		 virtual void setAll();
		 friend ostream& operator<<(ostream& os, const AbstrEmp& e);
		 virtual ~AbstrEmp() = 0;
	 };
	  
	 class Employee : public AbstrEmp
	 {
	 public:
		 Employee();
		 Employee(const string& fn, const string& ln, const string& j);
		 virtual void showAll()const;
		 virtual void setAll();
	 };

	 class Manager : virtual public AbstrEmp
	 {
	 private:
		 int _inchargeof;
	 protected:
		 int inChargeOf()const
		 {
			 return _inchargeof;
		 }
		 int& inChargeOf()
		 {
			 return _inchargeof;
		 }
	 public:
		 Manager();
		 Manager(const string& fn, const string& ln, const string& j0, int ico = 0);
		 Manager(const AbstrEmp& e, int ico);
		 Manager(const Manager& m);
		 virtual void showAll()const;
		 virtual void setAll();
	 };

	 class Fink : virtual public AbstrEmp
	 {
	 private:
		 string _reportsto;
	 protected:
		 const string reportsTo() const{ return _reportsto; }
		 string& reportsTo(){ return _reportsto; }
	 public:
		 Fink();
		 Fink(const string& fn, const string& ln, const string& j, const string& rpo);
		 Fink(const AbstrEmp& e, const string& rpo);
		 Fink(const Fink& e);
		 virtual void showAll()const;
		 virtual void setAll();
	 };

	 class HighFink: public Manager, public Fink
	 {
	 public:
		 HighFink();
		 HighFink(const string& fn, const string& ln, const string& j, const string& rpo, int ico);
		 HighFink(const AbstrEmp& e, const string& rpo, int ico);
		 HighFink(const Fink& f, int ico);
		 HighFink(const Manager& m, const string& rpo);
		 HighFink(const HighFink& h);
		 virtual void showAll()const;
		 virtual void setAll();
	 };
注意,该类层次结构使用了带虚基类的MI,所以要牢记这种情况下用于构造函数初始化列表的特殊规则。还需要注意的是,有些方法被声明为保护的。这可以简化一些HighFink方法的代码(例如,如果HightFink::showAll()只是调用Fink::showAll()和Manager::showAll(),则它将调用abstr_emp::ShowAll()两次)。提供类方法的实现,并在一个程序中对这些类进行测试。下面是一个小型测试程序:
#include <iostream>     
#include "Test.h"
#include <string>
using namespace std;
using namespace FableGame;
 
int main(int argc, const char * argv[])
{
	Employee em("Trip", "Harris", "Thumper");
	cout << em << endl;
	em.showAll();
	Manager ma("Amorphia", "Spindragon", "Nuancer", 5);
	cout << ma << endl;
	ma.showAll();
	Fink fi("Matt", "Oggs", "Oiler", "Juno Barr");
	cout << fi << endl;
	fi.showAll();
	HighFink hf(ma, "Curly Kew");
	hf.showAll();
	cout << "Press a key for next phase:\n";
	cin.get();
	HighFink hf2;
	hf2.setAll();

	cout << "Using an abstr_emp * pointer:\n";
	AbstrEmp* tri[4] = { &em, &fi, &hf, &hf2 };
	for (int i = 0; i < 4; ++i)
	{
		tri[i]->showAll();
	}
	return 0;
}
 
为什么没有定义赋值运算符?

为什么要将ShowAll()和SetAll()定义为虚的?

为什么要将abstr_emp定义为虚基类?

为什么highfink类没有数据部分?

为什么只需一个operator<<()版本?

如果使用下面的代码替换程序的结尾部分,将会发生什么情况?

abstr_emp str[4] = {em, fi, hf, hf2};
for(int i = 0; i < 4; ++i)
    tr[i].showAll()
程序:

Test.h

//
//  Test.h
//  HelloWorld
//
//  Created by feiyin001 on 16/12/21.
//  Copyright (c) 2016年 FableGame. All rights reserved.
//

#ifndef _Test_H_
#define _Test_H_
#include <iostream>
#include <string>
using namespace std;
namespace FableGame
{
	 class AbstrEmp
	 {
	 private:
		 string _fname;
		 string _lname;
		 string _job;
	 protected:
		 void setData();
		 void showData()const;
	 public:
		 AbstrEmp();
		 AbstrEmp(const std::string& fn, const string& ln, const string& j);
		 virtual void showAll()const;
		 virtual void setAll();
		 friend ostream& operator<<(ostream& os, const AbstrEmp& e);
		 virtual ~AbstrEmp();
	 };
	  
	 class Employee : public AbstrEmp
	 {
	 public:
		 Employee();
		 Employee(const string& fn, const string& ln, const string& j);
		 virtual void showAll()const;
		 virtual void setAll();
	 };

	 class Manager : virtual public AbstrEmp
	 {
	 private:
		 int _inchargeof;
	 protected:
		 int inChargeOf()const
		 {
			 return _inchargeof;
		 }
		 int& inChargeOf()
		 {
			 return _inchargeof;
		 }
		 void setData();
		 void showData()const;
	 public:
		 Manager();
		 Manager(const string& fn, const string& ln, const string& j0, int ico = 0);
		 Manager(const AbstrEmp& e, int ico);
		 Manager(const Manager& m);
		 virtual void showAll()const;
		 virtual void setAll();
	 };

	 class Fink : virtual public AbstrEmp
	 {
	 private:
		 string _reportsto;
	 protected:
		 const string reportsTo() const{ return _reportsto; }
		 string& reportsTo(){ return _reportsto; }
		 void setData();
		 void showData()const;
	 public:
		 Fink();
		 Fink(const string& fn, const string& ln, const string& j, const string& rpo);
		 Fink(const AbstrEmp& e, const string& rpo);
		 Fink(const Fink& e);
		 virtual void showAll()const;
		 virtual void setAll();
	 };

	 class HighFink: public Manager, public Fink
	 {
	 public:
		 HighFink();
		 HighFink(const string& fn, const string& ln, const string& j, const string& rpo, int ico);
		 HighFink(const AbstrEmp& e, const string& rpo, int ico);
		 HighFink(const Fink& f, int ico);
		 HighFink(const Manager& m, const string& rpo);
		 HighFink(const HighFink& h);
		 virtual void showAll()const;
		 virtual void setAll();
	 };
}
#endif
Test.cpp

//
//  Test.cpp
//  HelloWorld
//
//  Created by feiyin001 on 16/12/21.
//  Copyright (c) 2016年 FableGame. All rights reserved.
//

#include "Test.h"
#include <iostream> 
using namespace std;
using namespace FableGame;


FableGame::AbstrEmp::AbstrEmp()
{
	_fname = "";
	_lname = "";
	_job = "";
}

FableGame::AbstrEmp::AbstrEmp(const std::string& fn, const string& ln, const string& j)
{
	_fname = fn;
	_lname = ln;
	_job = j;
}

void FableGame::AbstrEmp::showAll() const
{
	showData();
}

void FableGame::AbstrEmp::setAll()
{
	setData();
}

FableGame::AbstrEmp::~AbstrEmp()
{

}

void FableGame::AbstrEmp::showData()const
{
	cout << "FName:" << _fname << " LName:" << _lname << " Job:" << _job << endl;
}

void FableGame::AbstrEmp::setData()
{
	cout << "Enter FName:";
	getline(cin, _fname);
	cout << "Enter LName:";
	getline(cin, _lname);
	cout << "Enter Job:";
	getline(cin, _job);
}

ostream& FableGame::operator<<(ostream& os, const AbstrEmp& e)
{
	os << e._fname << " " << e._lname << " " << e._job ;
	return os;
}

FableGame::Employee::Employee()
{

}

FableGame::Employee::Employee(const string& fn, const string& ln, const string& j) : AbstrEmp(fn, ln, j)
{

}

void FableGame::Employee::showAll() const
{
	AbstrEmp::showData();
}

void FableGame::Employee::setAll()
{
	AbstrEmp::setData();
}
 

FableGame::Manager::Manager()
{
	_inchargeof = 0;
}

FableGame::Manager::Manager(const string& fn, const string& ln, const string& j0, int ico /*= 0*/) : AbstrEmp(fn, ln, j0), _inchargeof(ico)
{

}

FableGame::Manager::Manager(const AbstrEmp& e, int ico) : AbstrEmp(e), _inchargeof(ico)
{

}

FableGame::Manager::Manager(const Manager& m) : AbstrEmp(m)
{
	_inchargeof = m._inchargeof;
}

void FableGame::Manager::showAll() const
{
	AbstrEmp::showData();
	showData();
}

void FableGame::Manager::setAll()
{
	AbstrEmp::setData();
	setData();
}

void FableGame::Manager::setData()
{
	cout << "Enter inchargeof:";
	cin >> _inchargeof;
	cin.get();
}

void FableGame::Manager::showData() const
{
	cout << "inchargeof:" << _inchargeof << endl;
}

FableGame::Fink::Fink()
{

}

FableGame::Fink::Fink(const string& fn, const string& ln, const string& j, const string& rpo) : AbstrEmp(fn, ln, j), _reportsto(rpo)
{

}

FableGame::Fink::Fink(const AbstrEmp& e, const string& rpo) : AbstrEmp(e), _reportsto(rpo)
{

}

FableGame::Fink::Fink(const Fink& e) : AbstrEmp(e)
{
	_reportsto = e._reportsto;
}

void FableGame::Fink::showAll() const
{
	AbstrEmp::showData();
	showData();
}

void FableGame::Fink::setAll()
{
	AbstrEmp::setData();
	setData();
}

void FableGame::Fink::setData()
{
	cout << "Enter _reportsto:";
	cin >> _reportsto;
	cin.get();
}

void FableGame::Fink::showData() const
{
	cout << "reportsto:" << _reportsto << endl;
}

FableGame::HighFink::HighFink()
{

}

FableGame::HighFink::HighFink(const string& fn, const string& ln, const string& j, const string& rpo, int ico) : 
AbstrEmp(fn, ln, j), Manager(fn, ln, j, ico), Fink(fn, ln, j, rpo)
{

}

FableGame::HighFink::HighFink(const AbstrEmp& e, const string& rpo, int ico) :AbstrEmp(e), Manager(e, ico), Fink(e, rpo)
{

}

FableGame::HighFink::HighFink(const Fink& f, int ico) : Fink(f), Manager(f, ico), AbstrEmp(f)
{

}

FableGame::HighFink::HighFink(const Manager& m, const string& rpo) : Fink(m, rpo), Manager(m), AbstrEmp(m)
{

}

FableGame::HighFink::HighFink(const HighFink& h) : Fink(h), Manager(h), AbstrEmp(h)
{

}

void FableGame::HighFink::showAll() const
{
	AbstrEmp::showData();
	Fink::showData();
	Manager::showData();
}

void FableGame::HighFink::setAll()
{
	AbstrEmp::setData();
	Fink::setData();
	Manager::setData();
}
main.cpp

#include <iostream>     
#include "Test.h"
#include <string>
using namespace std;
using namespace FableGame;
 
int main(int argc, const char * argv[])
{
	Employee em("Trip", "Harris", "Thumper");
	cout << em << endl;
	em.showAll();
	Manager ma("Amorphia", "Spindragon", "Nuancer", 5);
	cout << ma << endl;
	ma.showAll();
	Fink fi("Matt", "Oggs", "Oiler", "Juno Barr");
	cout << fi << endl;
	fi.showAll();
	HighFink hf(ma, "Curly Kew");
	hf.showAll();
	cout << "Press a key for next phase:\n";
	HighFink hf2;
	hf2.setAll();

	cout << "Using an abstr_emp * pointer:\n";
	AbstrEmp* tri[4] = { &em, &fi, &hf, &hf2 };
	for (int i = 0; i < 4; ++i)
	{
		tri[i]->showAll();
	}
	return 0;
}
 
为什么没有定义赋值运算符?

所有类的数据成员,都没有包含指针,在构造函数里面也没有使用new。所以不需要。

为什么要将ShowAll和SetAll定义为虚?

这样就可以在使用基类指针的时候,可以正确调用对象的函数。

为什么将abstr_emp定义为虚基类?

这样就不会有多个abstr_emp子对象了。

为什么highfink类没有数据部分?

这个看类的设计,没有新的数据需要记录就没有啦。

为什么只需要一个operator<<()版本?

这个。。。看需求吧。一个基类的版本肯定不能满足派生类的所有信息输出的。

使用新的代码,则数组内的元素是AbstrEmp。


写在最后:

想不到题目没有模板类的实现。不过也对,这本书也算是基础的内容,模板类对很多人来说,都是使用的。

更多涉及的是算法的实现吧。对于业务层的功能,好像很少需要自己创建模板类。至少我没写过。尴尬


转载于:https://www.cnblogs.com/fablegame/p/6430234.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值