Wallet
是一个跟踪货币的类。公然无视正确的面向对象编程实践,这个类有一个公共float amount
成员,可以跟踪钱包里有多少钱。它还有一个公共buyCandy()
方法,减去购买一些糖果所需的金额(1钱)。这个类只有一个构造函数,它可以获得初始金额。没有默认构造函数。
我使用这个类作为管道来询问有关C ++语法,指针/对象,方法和泛型的问题,因为我在这些主题中非常困惑。
我找不到大量的示例代码来改变方法中的向量,或者使用类对象作为向量的类型。
我正在尝试创建一种错误管理一堆钱包的evilBanker
方法。我们实际上将在main()
方法中执行所有操作,而不是使用正确的C ++约定。这是我希望实现的伪代码:
//comment lines will report the result that report should have if done on the vectors
func evilBanker() {
create a vector of wallets 'liked' with no elements
create a vector of wallets 'disliked' with 10 elements with -10 in their account
float evilAccount = 0;
//report liked = 0, disliked = -100, evilAccount = 0
'embezzleMoney' for 10 money from all of the 'disliked' wallets and add it to evilAccount
//report liked = 0, disliked = -200, evilAccount = 100
use 'buyCandy' to make the last 5 of the 'disliked' wallets buy candy
//report liked = 0, disliked = -205, evilAccount = 100
'likeSome' for first 5 of the 'disliked' elements into the 'liked' vector
//report liked = -100, disliked = -105, evilAccount = 100
'moveToFavorites' the 1st element in the 'disliked' vector to the 'favorites' vector
//report liked = -100 - 21 + 50, disliked = -105 - 21, evilAccount = 100
make a new wallet 'lucy' with 100 money in her account
add her to the favorites using the 'addToFavorites' method
//report liked = -71 + 100 + 100, disliked = -84, evilAccount = 100
reset the 'disliked' accounts removing all trace that they ever existed
//if possible 'disliked' would now be at an entirely new memory location
//but not sure if this is possible to do within a method
//report liked = 129, disliked = 0, evilAccount = 100
}
//Takes in the list of liked and disliked people and moves the first 'n' elements from the disliked list into the liked list
function 'likeSome' (likedVector, dislikedVector, n) {}
//Takes 'n' money from everyone inside of the vector and adds the money to the myAccount float
//As a precaution it should be impossible to add or remove elements from the vector only mutate the objects within the vector
//Should use the 'amount' field to do the subtraction
function 'embezzleMoney' (walletVector, n, &myAccount) {}
//Makes everyone in the vector within a range buy candy
//As a precaution it should be impossible to add or remove elements from the vector only mutate the objects within the vector
//Should use the 'buyCandy' method to do the subtraction
function 'buyCandy' (walletVector, lowerIndex, upperIndex) {}
//Adds 100 money to 'walletObjects' account then adds the wallet 'walletObject' to the 'walletVector'
function 'addToFavorites' (walletVector, walletObject) {}
//Moves the 'nth object from the dislikedVector to the likedVector and adds 50 money to its account
function 'moveToFavorites' (dislikedVector, likedVector, n) {}
//Deletes all of the wallets in the vector.
//To be thorough this will even delete the vector passed into it and create a new vector object to replace walletVector
function 'resetBank' (walletVector) {}
//Report the sum of the accounts of everyone in the vector.
//As a precaution it should be impossible to modify the vector or its contents inside of this method
function 'report' (walletVector) {}
我不知道如何在C ++中正确编写大多数这些方法,所以我希望你愿意至少输入每个方法所需的函数签名,并解释你的理由。
我意识到这个类的功能是荒谬的。这是我可以用来询问有关C ++语法的所有问题的最佳方案。
对于上面的所有例子,很高兴看到尽可能多的有效方法的例子来使这些功能发挥作用。
答案 0 :(得分:2)
vector
可以声明大小为0,任意类型(auto)
除外),如下所示:vector<SometypeHere> x
。如果要添加元素到最后,使用push_back(E)
。要创建初始大小的vector
,请使用vector<SometypeHere> x(n);
举个例子,我采用了likeSome(vector likes, vector, dislikes)
方法:
void likeSome(vector<Wallet>& likes, vector<Wallet> dislikes, int n)
{
for(int i = 0; i<n; i++)
likes.push_back( dislikes[i] );
}
对于方法resetBank
:
void resetBank(vector<Wallet>& wallets)
{
wallets.resize(0);
}
方法embezzleMoney
void embezzleMoney(const vector<Wallet>& walletVector, int n, float& myAccount)
{
for(int i = 0; i<walletVector.size(); i++)
{
if(walletVector[i].amount - n >= 0)
{
walletVector[i].amount -= n;
myAccount += n;
}
}
}
如果您需要更多示例,请与我们联系。
答案 1 :(得分:0)
尝试以下方法:
#include <iostream>
#include <vector>
using namespace std;
class Wallet
{
public:
float amount;
Wallet(float initialAmount) : amount(initialAmount) {}
void buyCandy() { amount -= 1.0; }
};
typedef vector<Wallet> WalletVector;
//Takes in the list of liked and disliked people and moves the first 'n' elements from the disliked list into the liked list
void likeSome(WalletVector &liked, WalletVector &disliked, size_t n)
{
liked.insert(liked.end(), disliked.begin(), disliked.begin()+n);
disliked.erase(disliked.begin(), disliked.begin()+n);
}
//Takes 'n' money from everyone inside of the vector and adds the money to the myAccount float
//As a precaution it should be impossible to add or remove elements from the vector only mutate the objects within the vector
//Should use the 'amount' field to do the subtraction
void embezzleMoney(const WalletVector &wallets, float n, float &myAccount)
{
for(size_t i = 0; i < wallets.size(); ++i)
{
const_cast<Wallet&>(wallets[i]).amount -= n;
myAccount += n;
}
}
//Makes everyone in the vector within a range buy candy
//As a precaution it should be impossible to add or remove elements from the vector only mutate the objects within the vector
//Should use the 'buyCandy' method to do the subtraction
void buyCandy(const WalletVector &wallets, size_t lowerIndex, size_t upperIndex)
{
for(size_t i = lowerIndex; i <= upperIndex; ++i)
const_cast<Wallet&>(wallets[i]).buyCandy();
}
//Adds 100 money to 'walletObjects' account then adds the wallet 'walletObject' to the 'walletVector'
void addToFavorites(WalletVector &wallets, Wallet w)
{
w.amount += 100;
wallets.push_back(w);
}
//Moves the 'nth object from the dislikedVector to the likedVector and adds 50 money to its account
void moveToFavorites(WalletVector &disliked, WalletVector &liked, size_t n)
{
Wallet w = disliked.at(n);
disliked.erase(disliked.begin()+n);
w.amount += 50;
liked.push_back(w);
}
//Deletes all of the wallets in the vector.
void resetBank(WalletVector &wallets)
{
wallets.clear();
}
//Report the sum of the accounts of everyone in the vector.
void report(const WalletVector &wallets)
{
float total = 0;
for (size_t i = 0; i < wallets.size(); ++i)
total += wallets[i].amount;
cout << total;
}
void report(const WalletVector &liked, const WalletVector &disliked, float evilAccount)
{
cout << "liked = ";
report(liked);
cout << ", disliked = ";
report(disliked);
cout << ", evilAccount = " << evilAccount << endl;
}
void evilBanker()
{
WalletVector liked;
WalletVector disliked(10, -10);
float evilAccount = 0;
report(liked, disliked, evilAccount);
// embezzle 10 money from all of the 'disliked' wallets and add it to evilAccount
embezzleMoney(disliked, 10, evilAccount);
report(liked, disliked, evilAccount);
// make the last 5 of the 'disliked' wallets buy candy
buyCandy(disliked, 5, 9);
report(liked, disliked, evilAccount);
// likeSome for first 5 of the 'disliked' elements into the 'liked' vector
likeSome(liked, disliked, 5);
report(liked, disliked, evilAccount);
// moveToFavorites' the 1st element in the 'disliked' vector to the 'favorites' vector
moveToFavorites(disliked, liked, 0);
report(liked, disliked, evilAccount);
// make a new wallet 'lucy' with 100 money in her account
// add her to the favorites using the 'addToFavorites' method
Wallet lucy(100);
addToFavorites(liked, lucy);
report(liked, disliked, evilAccount);
// reset the 'disliked' accounts removing all trace that they ever existed
resetBank(disliked);
report(liked, disliked, evilAccount);
}
int main()
{
evilBanker();
return 0;
}
输出:
liked = 0, disliked = -100, evilAccount = 0 liked = 0, disliked = -200, evilAccount = 100 liked = 0, disliked = -205, evilAccount = 100 liked = -100, disliked = -105, evilAccount = 100 liked = -71, disliked = -84, evilAccount = 100 liked = 129, disliked = -84, evilAccount = 100 liked = 129, disliked = 0, evilAccount = 100
可替换地:
#include <iostream>
#include <vector>
using namespace std;
class Wallet
{
public:
mutable float amount;
Wallet(float initialAmount) : amount(initialAmount) {}
void buyCandy() const { amount -= 1.0; }
};
typedef vector<Wallet> WalletVector;
//Takes in the list of liked and disliked people and moves the first 'n' elements from the disliked list into the liked list
void likeSome(WalletVector &liked, WalletVector &disliked, size_t n)
{
liked.insert(liked.end(), disliked.begin(), disliked.begin()+n);
disliked.erase(disliked.begin(), disliked.begin()+n);
}
//Takes 'n' money from everyone inside of the vector and adds the money to the myAccount float
//As a precaution it should be impossible to add or remove elements from the vector only mutate the objects within the vector
//Should use the 'amount' field to do the subtraction
void embezzleMoney(const WalletVector &wallets, float n, float &myAccount)
{
for(size_t i = 0; i < wallets.size(); ++i)
{
wallets[i].amount -= n;
myAccount += n;
}
}
//Makes everyone in the vector within a range buy candy
//As a precaution it should be impossible to add or remove elements from the vector only mutate the objects within the vector
//Should use the 'buyCandy' method to do the subtraction
void buyCandy(const WalletVector &wallets, size_t lowerIndex, size_t upperIndex)
{
for(size_t i = lowerIndex; i <= upperIndex; ++i)
wallets[i].buyCandy();
}
//Adds 100 money to 'walletObjects' account then adds the wallet 'walletObject' to the 'walletVector'
void addToFavorites(WalletVector &wallets, Wallet w)
{
w.amount += 100;
wallets.push_back(w);
}
//Moves the 'nth object from the dislikedVector to the likedVector and adds 50 money to its account
void moveToFavorites(WalletVector &disliked, WalletVector &liked, size_t n)
{
Wallet w = disliked.at(n);
disliked.erase(disliked.begin()+n);
w.amount += 50;
liked.push_back(w);
}
//Deletes all of the wallets in the vector.
void resetBank(WalletVector &wallets)
{
wallets.clear();
}
//Report the sum of the accounts of everyone in the vector.
void report(const WalletVector &wallets)
{
float total = 0;
for (size_t i = 0; i < wallets.size(); ++i)
total += wallets[i].amount;
cout << total;
}
void report(const WalletVector &liked, const WalletVector &disliked, float evilAccount)
{
cout << "liked = ";
report(liked);
cout << ", disliked = ";
report(disliked);
cout << ", evilAccount = " << evilAccount << endl;
}
void evilBanker()
{
WalletVector liked;
WalletVector disliked(10, -10);
float evilAccount = 0;
report(liked, disliked, evilAccount);
// embezzle 10 money from all of the 'disliked' wallets and add it to evilAccount
embezzleMoney(disliked, 10, evilAccount);
report(liked, disliked, evilAccount);
// make the last 5 of the 'disliked' wallets buy candy
buyCandy(disliked, 5, 9);
report(liked, disliked, evilAccount);
// likeSome for first 5 of the 'disliked' elements into the 'liked' vector
likeSome(liked, disliked, 5);
report(liked, disliked, evilAccount);
// moveToFavorites' the 1st element in the 'disliked' vector to the 'favorites' vector
moveToFavorites(disliked, liked, 0);
report(liked, disliked, evilAccount);
// make a new wallet 'lucy' with 100 money in her account
// add her to the favorites using the 'addToFavorites' method
Wallet lucy(100);
addToFavorites(liked, lucy);
report(liked, disliked, evilAccount);
// reset the 'disliked' accounts removing all trace that they ever existed
resetBank(disliked);
report(liked, disliked, evilAccount);
}
int main()
{
evilBanker();
return 0;
}
输出:
liked = 0, disliked = -100, evilAccount = 0 liked = 0, disliked = -200, evilAccount = 100 liked = 0, disliked = -205, evilAccount = 100 liked = -100, disliked = -105, evilAccount = 100 liked = -71, disliked = -84, evilAccount = 100 liked = 129, disliked = -84, evilAccount = 100 liked = 129, disliked = 0, evilAccount = 100
如上所示,你的“作为预防措施,不应该在向量中添加或删除元素只能改变向量”中的对象要求可能有点不切实际。虽然可以完成(如上所示),但不应该这样做。
问题是,当您通过vector
引用访问const
时,它会提供对其元素的只读(const
)访问权限。这意味着如果向量直接保存实际对象,则通常不能在其上调用任何非const方法或修改其数据成员。您必须使用有风险的const_cast
类型转换来删除const
- 或者将数据成员声明为mutable
。正如您在上面所看到的,后者可以使Wallet::buyCandy()
成为一种奇怪的东西 - 它是一种const
方法,可以修改被调用对象的amount
。
要正确地解决此 ,在满足您的要求的同时,您可以更改代码以使用包含非const指针的向量来动态分配对象。然后,您可以对指针本身进行只读访问,同时具有对其指向的对象的可写访问权限,例如:
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class Wallet
{
public:
float amount;
Wallet(float initialAmount) : amount(initialAmount) {}
void buyCandy() { amount -= 1.0; }
};
using WalletPtr = unique_ptr<Wallet>;
using WalletVector = vector<WalletPtr>;
//Takes in the list of liked and disliked people and moves the first 'n' elements from the disliked list into the liked list
void likeSome(WalletVector &liked, WalletVector &disliked, size_t n)
{
while (n > 0)
{
WalletPtr w = move(disliked.front());
disliked.erase(disliked.begin());
liked.push_back(move(w));
--n;
}
}
//Takes 'n' money from everyone inside of the vector and adds the money to the myAccount float
//As a precaution it should be impossible to add or remove elements from the vector only mutate the objects within the vector
//Should use the 'amount' field to do the subtraction
void embezzleMoney(const WalletVector &wallets, float n, float &myAccount)
{
for(size_t i = 0; i < wallets.size(); ++i)
{
wallets[i]->amount -= n;
myAccount += n;
}
}
//Makes everyone in the vector within a range buy candy
//As a precaution it should be impossible to add or remove elements from the vector only mutate the objects within the vector
//Should use the 'buyCandy' method to do the subtraction
void buyCandy(const WalletVector &wallets, size_t lowerIndex, size_t upperIndex)
{
for(size_t i = lowerIndex; i <= upperIndex; ++i)
wallets[i]->buyCandy();
}
//Adds 100 money to 'walletObjects' account then adds the wallet 'walletObject' to the 'walletVector'
void addToFavorites(WalletVector &wallets, WalletPtr w)
{
w->amount += 100;
wallets.push_back(move(w));
}
//Moves the 'nth object from the dislikedVector to the likedVector and adds 50 money to its account
void moveToFavorites(WalletVector &disliked, WalletVector &liked, size_t n)
{
WalletPtr w = move(disliked.at(n));
disliked.erase(disliked.begin()+n);
w->amount += 50;
liked.push_back(move(w));
}
//Deletes all of the wallets in the vector.
void resetBank(WalletVector &wallets)
{
wallets.clear();
}
//Report the sum of the accounts of everyone in the vector.
//As a precaution it should be impossible to modify the vector or its contents inside of this method
void report(const WalletVector &wallets)
{
float total = 0;
for (size_t i = 0; i < wallets.size(); ++i)
total += wallets[i]->amount;
cout << total;
}
void report(const WalletVector &liked, const WalletVector &disliked, float evilAccount)
{
cout << "liked = ";
report(liked);
cout << ", disliked = ";
report(disliked);
cout << ", evilAccount = " << evilAccount << endl;
}
void evilBanker()
{
WalletVector liked;
WalletVector disliked;
for (int i = 0; i < 10; ++i)
{
WalletPtr w(new Wallet(-10));
disliked.push_back(move(w));
}
float evilAccount = 0;
report(liked, disliked, evilAccount);
// embezzle 10 money from all of the 'disliked' wallets and add it to evilAccount
embezzleMoney(disliked, 10, evilAccount);
report(liked, disliked, evilAccount);
// make the last 5 of the 'disliked' wallets buy candy
buyCandy(disliked, 5, 9);
report(liked, disliked, evilAccount);
// likeSome for first 5 of the 'disliked' elements into the 'liked' vector
likeSome(liked, disliked, 5);
report(liked, disliked, evilAccount);
// moveToFavorites' the 1st element in the 'disliked' vector to the 'favorites' vector
moveToFavorites(disliked, liked, 0);
report(liked, disliked, evilAccount);
// make a new wallet 'lucy' with 100 money in her account
// add her to the favorites using the 'addToFavorites' method
WalletPtr lucy(new Wallet(100));
addToFavorites(liked, move(lucy));
report(liked, disliked, evilAccount);
// reset the 'disliked' accounts removing all trace that they ever existed
resetBank(disliked);
report(liked, disliked, evilAccount);
}
int main()
{
evilBanker();
return 0;
}
输出:
liked = 0, disliked = -100, evilAccount = 0 liked = 0, disliked = -200, evilAccount = 100 liked = 0, disliked = -205, evilAccount = 100 liked = -100, disliked = -105, evilAccount = 100 liked = -71, disliked = -84, evilAccount = 100 liked = 129, disliked = -84, evilAccount = 100 liked = 129, disliked = 0, evilAccount = 100