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

时间:2017-12-13 03:10:14

标签: c++ stl

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 ++语法的所有问题的最佳方案。

对于上面的所有例子,很高兴看到尽可能多的有效方法的例子来使这些功能发挥作用。

2 个答案:

答案 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

Live demo

可替换地:

#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

Live demo

如上所示,你的“作为预防措施,不应该在向量中添加或删除元素只能改变向量”中的对象要求可能有点不切实际。虽然可以完成(如上所示),但不应该这样做。

问题是,当您通过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

Live demo