C++中各种向量突变方法的语法


Wallet

是一个跟踪货币的类。由于公然无视适当的面向对象编程实践,这个类有一个公共float amount成员来跟踪钱包里有多少钱。它还有一个公共buyCandy()方法,可以减去购买糖果所需的金额(1 美元)。此类只有一个接受初始资金的构造函数。没有默认构造函数。

我使用这个类作为管道来询问有关 STL 语法、指针/对象、方法和泛型的问题 C++,因为我对这些主题非常困惑。

我找不到大量在方法内部改变向量或使用类对象作为向量类型的示例代码。

我正在尝试创建一种管理不善的一堆钱包的evilBanker方法。我们实际上不是使用正确的C++约定,而是在main()方法中执行所有操作。以下是我希望实现的目标的伪代码:

//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++。

对于上面的所有示例,很高兴看到尽可能多的有效方法的示例来使函数工作。

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;
}
}
}

如果您需要更多示例,请告诉我。

尝试以下操作:

#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;
}

输出:

喜欢 = 0,不喜欢 = -100,邪恶帐户 = 0 喜欢 = 0,不喜欢 = -200,邪恶帐户 = 100 喜欢 = 0,不喜欢 = -205,邪恶帐户 = 100 喜欢 = -100,不喜欢 = -105,邪恶帐户 = 100 喜欢 = -71,不喜欢 = -84,邪恶帐户 = 100 喜欢 = 129,不喜欢 = -84,邪恶帐户 = 100 喜欢 = 129,不喜欢 = 0,邪恶帐户 = 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;
}

输出:

喜欢 = 0,不喜欢 = -100,邪恶帐户 = 0 喜欢 = 0,不喜欢 = -200,邪恶帐户 = 100 喜欢 = 0,不喜欢 = -205,邪恶帐户 = 100 喜欢 = -100,不喜欢 = -105,邪恶帐户 = 100 喜欢 = -71,不喜欢 = -84,邪恶帐户 = 100 喜欢 = 129,不喜欢 = -84,邪恶帐户 = 100 喜欢 = 129,不喜欢 = 0,邪恶帐户 = 100

现场演示

如上所述,您的">作为预防措施,应该不可能在向量中添加或删除元素,只会改变向量中的对象"的要求可能有点不切实际。 尽管可以完成(如上所述),但不应以这种方式完成。

问题是,当你通过const引用访问vector时,它提供了对其元素的只读(const)访问。 这意味着如果向量直接保存实际对象,则通常不能对它们调用任何非常量方法或修改它们的数据成员。 您必须使用有风险的const_cast类型转换来删除const-ness,或将数据成员声明为mutable。 正如你在上面看到的,后者可以使Wallet::buyCandy()成为一个奇怪的问题 - 它是一种const方法,可以修改调用它的对象的amount

若要正确解决此问题,同时满足要求,可以更改代码以使用包含指向动态分配对象的非常量指针的向量。 然后,您可以对指针本身具有只读访问权限,同时对它们指向的对象具有可写访问权限,例如:

#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;
}

输出:

喜欢 = 0,不喜欢 = -100,邪恶帐户 = 0 喜欢 = 0,不喜欢 = -200,邪恶帐户 = 100 喜欢 = 0,不喜欢 = -205,邪恶帐户 = 100 喜欢 = -100,不喜欢 = -105,邪恶帐户 = 100 喜欢 = -71,不喜欢 = -84,邪恶帐户 = 100 喜欢 = 129,不喜欢 = -84,邪恶帐户 = 100 喜欢 = 129,不喜欢 = 0,邪恶帐户 = 100

现场演示

最新更新