向量语法是什么

时间:2018-12-09 10:37:13

标签: c++

这是我的功能:

void Gladiator::display()

{

  cout << name << ":\nHealth: " << curHealth << '/' << maxHealth <<

    "\nEvasion: " << evasion << "\nCritical: " << critical <<

    "\nDamage: " << dmgMin << '-' << dmgMin + dmgRange + 1 << "\n\n";

}

我需要语法帮助来显示上述函数的统计信息,并且我为蓝队和红队创建角斗士向量的语法是否正确?非常感谢。

cout << "A battle will soon commence... First the Teams must be created." << endl;

        vector<Gladiator> redTeam; // is the syntax correct for this one too?

        vector<Gladiator> blueTeam;

        cout << "Red Team's Stats: " << endl;

        Gladiator.display(redTeam); //this is the part where I don't know the syntax of displaying the stats for redTeam vector.

        cout << "Blue Team's Stats: " << endl;

        blueTeam.display(); //syntax for this is wrong too.

4 个答案:

答案 0 :(得分:1)

您有一个误解。函数from ibapi.wrapper import EWrapper from ibapi.client import EClient from ibapi.contract import Contract as IBcontract from threading import Thread import queue import datetime DEFAULT_HISTORIC_DATA_ID=50 DEFAULT_GET_CONTRACT_ID=43 ## marker for when queue is finished FINISHED = object() STARTED = object() TIME_OUT = object() class finishableQueue(object): def __init__(self, queue_to_finish): self._queue = queue_to_finish self.status = STARTED def get(self, timeout): """ Returns a list of queue elements once timeout is finished, or a FINISHED flag is received in the queue :param timeout: how long to wait before giving up :return: list of queue elements """ contents_of_queue=[] finished=False while not finished: try: current_element = self._queue.get(timeout=timeout) if current_element is FINISHED: finished = True self.status = FINISHED else: contents_of_queue.append(current_element) ## keep going and try and get more data except queue.Empty: ## If we hit a time out it's most probable we're not getting a finished element any time soon ## give up and return what we have finished = True self.status = TIME_OUT return contents_of_queue def timed_out(self): return self.status is TIME_OUT class TestWrapper(EWrapper): """ The wrapper deals with the action coming back from the IB gateway or TWS instance We override methods in EWrapper that will get called when this action happens, like currentTime Extra methods are added as we need to store the results in this object """ def __init__(self): self._my_contract_details = {} self._my_historic_data_dict = {} self._my_errors = queue.Queue() ## error handling code def init_error(self): error_queue=queue.Queue() self._my_errors = error_queue def get_error(self, timeout=5): if self.is_error(): try: return self._my_errors.get(timeout=timeout) except queue.Empty: return None return None def is_error(self): an_error_if=not self._my_errors.empty() return an_error_if def error(self, id, errorCode, errorString): ## Overriden method errormsg = "IB error id %d errorcode %d string %s" % (id, errorCode, errorString) self._my_errors.put(errormsg) ## get contract details code def init_contractdetails(self, reqId): contract_details_queue = self._my_contract_details[reqId] = queue.Queue() return contract_details_queue def contractDetails(self, reqId, contractDetails): ## overridden method if reqId not in self._my_contract_details.keys(): self.init_contractdetails(reqId) self._my_contract_details[reqId].put(contractDetails) def contractDetailsEnd(self, reqId): ## overriden method if reqId not in self._my_contract_details.keys(): self.init_contractdetails(reqId) self._my_contract_details[reqId].put(FINISHED) ## Historic data code def init_historicprices(self, tickerid): historic_data_queue = self._my_historic_data_dict[tickerid] = queue.Queue() return historic_data_queue def historicalData(self, tickerid , bar): ## Overriden method ## Note I'm choosing to ignore barCount, WAP and hasGaps but you could use them if you like bardata=(bar.date, bar.open, bar.high, bar.low, bar.close, bar.volume) historic_data_dict=self._my_historic_data_dict ## Add on to the current data if tickerid not in historic_data_dict.keys(): self.init_historicprices(tickerid) historic_data_dict[tickerid].put(bardata) def historicalDataEnd(self, tickerid, start:str, end:str): ## overriden method if tickerid not in self._my_historic_data_dict.keys(): self.init_historicprices(tickerid) self._my_historic_data_dict[tickerid].put(FINISHED) class TestClient(EClient): """ The client method We don't override native methods, but instead call them from our own wrappers """ def __init__(self, wrapper): ## Set up with a wrapper inside EClient.__init__(self, wrapper) def resolve_ib_contract(self, ibcontract, reqId=DEFAULT_GET_CONTRACT_ID): """ From a partially formed contract, returns a fully fledged version :returns fully resolved IB contract """ ## Make a place to store the data we're going to return contract_details_queue = finishableQueue(self.init_contractdetails(reqId)) print("Getting full contract details from the server... ") self.reqContractDetails(reqId, ibcontract) ## Run until we get a valid contract(s) or get bored waiting MAX_WAIT_SECONDS = 10 new_contract_details = contract_details_queue.get(timeout = MAX_WAIT_SECONDS) while self.wrapper.is_error(): print(self.get_error()) if contract_details_queue.timed_out(): print("Exceeded maximum wait for wrapper to confirm finished - seems to be normal behaviour") if len(new_contract_details)==0: print("Failed to get additional contract details: returning unresolved contract") return ibcontract if len(new_contract_details)>1: print("got multiple contracts using first one") new_contract_details=new_contract_details[0] resolved_ibcontract=new_contract_details.contract return resolved_ibcontract def get_IB_historical_data(self, ibcontract, durationStr="1 Y", barSizeSetting="1 day", tickerid=DEFAULT_HISTORIC_DATA_ID): """ Returns historical prices for a contract, up to today ibcontract is a Contract :returns list of prices in 4 tuples: Open high low close volume """ ## Make a place to store the data we're going to return historic_data_queue = finishableQueue(self.init_historicprices(tickerid)) # Request some historical data. Native method in EClient self.reqHistoricalData( tickerid, # tickerId, ibcontract, # contract, datetime.datetime.today().strftime("%Y%m%d %H:%M:%S %Z"), # endDateTime, durationStr, # durationStr, barSizeSetting, # barSizeSetting, "TRADES", # whatToShow, 1, # useRTH, 1, # formatDate False, # KeepUpToDate <<==== added for api 9.73.2 [] ## chartoptions not used ) ## Wait until we get a completed data, an error, or get bored waiting MAX_WAIT_SECONDS = 10 print("Getting historical data from the server... could take %d seconds to complete " % MAX_WAIT_SECONDS) historic_data = historic_data_queue.get(timeout = MAX_WAIT_SECONDS) while self.wrapper.is_error(): print(self.get_error()) if historic_data_queue.timed_out(): print("Exceeded maximum wait for wrapper to confirm finished - seems to be normal behaviour") self.cancelHistoricalData(tickerid) return historic_data class TestApp(TestWrapper, TestClient): def __init__(self, ipaddress, portid, clientid): TestWrapper.__init__(self) TestClient.__init__(self, wrapper=self) self.connect(ipaddress, portid, clientid) thread = Thread(target = self.run) thread.start() setattr(self, "_thread", thread) self.init_error() #if __name__ == '__main__': app = TestApp("127.0.0.1", 4001, 1) ibcontract = IBcontract() ibcontract.secType = "FUT" ibcontract.lastTradeDateOrContractMonth="201901" ibcontract.symbol="GE" ibcontract.exchange="GLOBEX" resolved_ibcontract=app.resolve_ib_contract(ibcontract) historic_data = app.get_IB_historical_data(resolved_ibcontract) print(historic_data) app.disconnect() 是类Gladiator::Display()的成员函数。该函数不接受任何参数,因此您不能按原样调用它。

我建议您寻找Gladiatorfunction overloading函数,因为它们将帮助您了解需要做什么。

我将添加一个static函数static,如下所示:

Gladiator.h

Galdiator::Display(const std::vector<Gladiator>& team)

Gladiator.cpp

class Gladiator{
public:
    //.. your functions
    void Display() const; // PLEASE ADD TRAILING const TO ALLOW THIS FUNCTION TO BE CALLED ON const Gladiator objects.
    static void Display(const std::vector<Gladiator>& team);
private:
    // data
}

然后您可以将其称为:

static void Gladiator::Display(const std::vector<Gladiator>& team){
     for(auto& glad : team)
         glad.Display();
}

请注意,不可能像在 Gladiator::Display(redTeam); // or blueTeam 中那样拥有extension methods,在那里您可以使用静态类扩展现有的类。因此,无法调用:

C#

由于blueTeam.Display(); blueTeam,不包含函数std::vector

但是,您可以使用流操作符重载和重载Display()来使其变通,使其接受std::ostream并显示它,以解决此问题。我不建议您对此进行深入研究,因为问题表明某些基础知识不足。


无论如何,

std::vector<Gladiator>

如果存在vector<Gladiator> redTeam; 的默认构造函数,则完全有效。如果您想给它一个尺寸,可以使用:

Gladiator

这将创建一个带有int n = 10; // number of gladiators per team vector<Gladiator> redTeam(n); 角斗士的向量。请注意,仅当类10具有默认构造函数Gladiator时,这才有效。如果您创建了另一个构造函数,则默认构造函数将不会由编译器自动生成。

希望这会有所帮助。

答案 1 :(得分:0)

首先,尽管语法有效,但此处的向量为空:

vector<Gladiator> redTeam;

因此,您需要在显示任何内容之前向该矢量添加元素。
有关该主题的更多信息,请参见std::vector::push_back


语法错误:

Gladiator.display(redTeam);

display函数不接受任何参数。您打算做的是(假设您向向量添加了一些元素):

for (const auto& elm : redTeam) {
    elm.display();
}

在这里,我们在向量中的每个元素上调用display方法。
有关该主题的更多信息,请参见Range-based for loop

答案 2 :(得分:0)

关于Gladiator.display(redTeam);:否,display不接受参数,也不接受参数。该功能可以显示一个Gladiator的统计信息,并且理想情况下,对于角斗士要战斗的团队应该是不可知的。

相反,创建一个Team类来保存角斗士的向量,并向其中添加一个display成员函数,该成员函数将循环所有角斗士并调用其display函数。

struct Team {
    void display() const {
        for(const Gladiator& g : gladiators) {
            g.display();
        }
    }
};

Team类也将在您以后想要添加与另一个团队战斗的功能时派上用场。然后,Fight类中的Team函数将在其所包含的角斗士中调用Fight函数。

display的两个函数都可以做成流运算符,以使与标准流的集成变得不明显,因此您可以这样做:

std::cout << a_gladiator; // print stats for one gladiator
std::cout << redteam;     // print stats for all gladiators in a team

这是一个示例,其中我用流运算符替换了display函数,并且由于随机性可能是战斗中的很大一部分,因此我还添加了<random>库的示例用法,在两个类中如何实现Fight函数的示例。

#include <iostream>
#include <vector>
#include <random>

// "prng" will be the pseudo random number generator when fighting
// https://en.cppreference.com/w/cpp/header/random
std::random_device rd;
std::mt19937 prng(rd());

enum Result { r_loss=-1, r_draw=0, r_win=1};

Result win_or_loss(int h, int a) {
    int r = h-a;
    return (r==0) ? r_draw : (r>0?r_win:r_loss);
}
//-----------------------------------------------------------------------------
struct Gladiator {
    std::string name;
    int maxHealth;
    int curHealth;
    int evasion;
    int critical;
    // "damage" will hold the min and max values of damage
    // and can be used with a pseudo random number generator
    // to get the value of one strike that the Gladiator
    // delivers
    std::uniform_int_distribution<int> damage;

    Gladiator(const std::string& Name, int MaxHealth, int Evasion,
              int Critical, int DmgMin, int DmgRange) :
        name(Name),
        maxHealth(MaxHealth),
        curHealth(maxHealth),
        evasion(Evasion),
        critical(Critical),
        damage(DmgMin, DmgMin+DmgRange) // initialize with DmgMin and DmgRange
    {}

    // return r_win if this gladiator wins or r_loss if the opponent wins
    //        or r_draw if it's a draw
    Result Fight(Gladiator& opponent) {
        // perhaps reset health here, or at the end of the fight
        curHealth = maxHealth;
        opponent.curHealth = opponent.maxHealth;

        std::cout << " The fight between " << name << " and " << opponent.name << " begins!\n";
        // fight loop
        while( curHealth>0 && opponent.curHealth>0 ) {
            // use of evasion & critical must be added

            // use the "damage" uniform int distributions with the
            // random number generator to get the values for the hits
            int my_hit = damage(prng);
            int opponents_hit = opponent.damage(prng);
            // add cool fight messages
            std::cout << "  " << name << " hit " << opponent.name << ", doing " << my_hit << " hp damage.\n";
            std::cout << "  " << opponent.name << " hit " << name << ", doing " << opponents_hit << " hp damage.\n";
            curHealth -= opponents_hit;
            opponent.curHealth -= my_hit;
        }
        // figure out who won
        Result r = win_or_loss(curHealth, opponent.curHealth);
        if(r==r_win) std::cout << " Gladiator " << name << " won!\n";
        else if(r==r_loss) std::cout << " Gladiator " << opponent.name << " won!\n";
        else std::cout << " It was a draw!\n";
        return r;
    }

    // declare a function (in the form of a stream operator) for streaming
    // a gladiator to an output stream, like std::cout
    friend std::ostream& operator<<(std::ostream&, const Gladiator&);
};

// definition of the output stream operator for a Gladiator
std::ostream& operator<<(std::ostream& os, const Gladiator& g) {
    os << " " << g.name << ":\n  Health: " << g.curHealth << '/' << g.maxHealth <<
        "\n  Evasion: " << g.evasion << "\n  Critical: " << g.critical <<
        "\n  Damage: " << g.damage.min() << '-' << g.damage.max() << "\n\n";
    return os;
}
//-----------------------------------------------------------------------------
struct Team {
    std::string name;
    std::vector<Gladiator> m_gladiators;

    Team(const std::string& Name) : Team(Name, {}) {}
    Team(const std::string& Name, std::vector<Gladiator>&& gv) :
        name(Name),
        m_gladiators(std::move(gv))
    {}

    // return r_win if this team wins or r_loss if the opponent team wins
    //        or r_draw if it's a draw    
    Result Fight(Team& opponent) {
        unsigned wins=0, losses=0;
        std::cout << "Team " << name << " vs. " << opponent.name << "\n";
        for(Gladiator& my_gladiator : m_gladiators) {
            for(Gladiator& opponent_gladiator : opponent.m_gladiators) {
                Result result = my_gladiator.Fight(opponent_gladiator);
                if(result>0) {
                    ++wins;
                } else if(result<0) {
                    ++losses;
                }
            }
        }
        Result r = win_or_loss(wins, losses);
        if(r==r_win) std::cout << "Team " << name << " won!\n";
        else if(r==r_loss) std::cout << "Team " << opponent.name << " won!\n";
        else std::cout << "It was a draw\n";
        return r;
    }

    // Just like for an individal Gladiator, declare a stream operator.
    friend std::ostream& operator<<(std::ostream&, const Team&);
};

// stream all gladiators in a Team
std::ostream& operator<<(std::ostream& os, const Team& t) {
    os << "Team " << t.name << " stats:\n";
    for(const auto& g : t.m_gladiators) {
        std::cout << g; // this uses the Gladiator output stream operator
    }
    return os;
}
//-----------------------------------------------------------------------------

int main() {
    std::cout << "A battle will soon commence... First the Teams must be created.\n";

    // if you'd like a dynamic amount of teams, you can make a Team vector like this:
    std::vector <Team> teams = {
        {"Red",
            {
                {"Spartacus", 100, 25, 27, 10, 17},
                {"Crixus",     99, 24, 26, 12, 13}
            }
        },
        {"Blue",
            {
                {"Commodus",  101, 30, 28, 11, 16},
                {"Tetraites",  98, 31, 29, 10, 15}
            }
        }
    };

    // print info about all teams
    for(const auto& team : teams) std::cout << team;

    // let all teams fight
    for(auto it_a=teams.begin(); it_a<(teams.end()-1); ++it_a) {
        for(auto it_b=it_a+1; it_b<teams.end(); ++it_b) {
            (*it_a).Fight(*it_b);
        }
    }

    /*
    std::cout << "------\n";

    // or if you'd like to treat them separately, you can create
    // referenses to the teams:

    Team& redTeam = teams[0];
    Team& blueTeam = teams[1];

    // and use them individually
    std::cout << redTeam;
    std::cout << blueTeam;

    redTeam.Fight(blueTeam);
    */
}

答案 3 :(得分:-1)

std::vector<Gladiator> v = {};

v.push_back(Gladiator());

// Iterate and print values of vector
for(Gladiator g : v) {
    g.Display();
}

https://en.cppreference.com/w/cpp/container/vector

有关更多信息,请参见以下内容。

How can I create objects while adding them into a vector?