【问题标题】:how to make/access instances of a class如何创建/访问类的实例
【发布时间】:2021-12-27 09:31:31
【问题描述】:

我正在尝试创建一个类的实例,我可以随时访问它,这是我认为管理这些数据的最佳方式,如果不是,请说出来。我正在尝试存储来自 binance.us 的每个加密货币的数据。这是我的班级结构:

class CryptoStats {
public:
    std::string name;
    std::string lastPriceStr;
    int lastPrice = 0;
    int score = 0;
    int priceHistory[2] = { 0,0 }; // one column for time, other for price
};

我想知道如何制作它的单个实例,例如 CryptoStats["BTCUSD"],然后我可以在其中编辑它,检查它是否存在等。 我尝试将它存储在一个集合中,但它不允许我:

std::set<std::pair<std::string, CryptoStats>> cryptoStats;

基本上我正在寻找与这个 Lua 表结构等效的 C++:

local cryptoStats = {
["BTCUSD"] = {lastPrice = 0, lastPriceStr = "0", score = 0, priceHistory = {0,0}},
["ETHUSD"] = {lastPrice = 0, lastPriceStr = "0", score = 0, priceHistory = {0,0}}
}

【问题讨论】:

  • 看起来更像std::map&lt;std::string, CryptoStats&gt; cryptoStats;en.cppreference.com/w/cpp/container/map
  • 您可能正在寻找struct 而不是class
  • @NO_NAME 和有什么区别?
  • @Klaus 好的,如果所有成员都是公共的,那么类也支持聚合初始化是对的。但是,仍然存在概念上的差异。使用类意味着封装和一些允许以受控方式修改私有成员的功能。如果您只想要一个普通的非封装结构,而您使用的是一个类,那么您会误导读者。只是让代码工作,还有一些好的做法,虽然不是严格要求,但也很重要。

标签: c++ class object


【解决方案1】:

您可以使用 std::map ,在您的情况下 name 不再属于您的课程。但是您也可以在类中使用包含name 的集合,并使用它从您的容器中找到它。

以下代码提供了两种选择:

class CryptoStatsWithoutName {
public:
    std::string lastPriceStr;
    int lastPrice = 0;
    int score = 0;
    int priceHistory[2] = { 0,0 }; // one column for time, other for price
};

class CryptoStats{
public:
    std::string name;
    std::string lastPriceStr;
    int lastPrice = 0;
    int score = 0;
    int priceHistory[2] = { 0,0 }; // one column for time, other for price

    // a set is always be sorted, as this, it needs for user defined types
    // a comparison operator
    bool operator<( const CryptoStats& outer) const
    {   
        return name< outer.name;
    }   
};

// if we want to use std::set<>::find we have to provide additional comparison operators
// if the key we search for is not the stored user defined type
bool operator<( const CryptoStats& cs, const std::string& key) { return cs.name < key; }
bool operator<( const std::string& key, const CryptoStats& cs) { return key < cs.name; }


int main()
{   
    std::map<std::string, CryptoStatsWithoutName> cryptoStatsWithoutName=
    {   
        {"BTCUSD", {"1", 1, 1,{1,1}}},
        {"ETHUSD", {"2" ,2, 2, {2,2}}}
    };
    
// attention: if the key is not found, a new feault initialized element will be inserted into the map!
    std::cout << cryptoStatsWithoutName[ "BTCUSD" ].lastPrice << std::endl;
    
    std::set< CryptoStats, std::less<> > cryptoStats =
    {   
        {"BTCUSD", "1", 1, 1,{1,1}},
        {"ETHUSD", "2" ,2, 2,{2,2}}
    };
    
    // attention: If key is not found you access `end()` which will crash your prog. Better you check that your returned iterator is valid!
    std::cout << cryptoStats.find("ETHUSD")->lastPrice << std::endl;
}

注意: 如果您搜索不存在的密钥,则代码将失败。如果是地图,它将使用给定的搜索键插入一个新的默认初始化元素,我相信这不是故意的。在 std::find 的情况下,您最好在访问返回的数据之前检查 find 是否返回 end()。在最后一种情况下,您的程序可能会抛出异常或通过访问不存在的数据而终止。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多