对对象成员、对象内部、向量内部所做的更改不会在方法结束后继续存在。 C++

Posted

技术标签:

【中文标题】对对象成员、对象内部、向量内部所做的更改不会在方法结束后继续存在。 C++【英文标题】:Changes made to member of object, inside object, inside a vector, do not survive end of method. C++ 【发布时间】:2020-05-30 00:27:15 【问题描述】:

抱歉标题。我无法做出比这更具有描述性或更清晰的东西..

我正在尝试做一些类似于非常基本的拍卖的事情。

为了简单起见,我将在这里列出每个课程的要点。 我也将所有内容从西班牙语翻译成英语,所以如果有错别字,就在这里。实际代码编译正常。

这里涉及到四个类:

class Person

private:
    std::string name;


class Offer

private:
    int amount;
    Person *bidder;


class Item

private:
    int itemNumber;
    std::string itemName;
    Offer *biggestBidder;

public:
    Item(int, std::string)
    void setbiggestBidder(Offer* const &); // I did this '* const &' thing while trying solutions
    Oferta *getBiggestBidder();


class Auction

private:
    std::vector<Item> itemCollection;
    int amountOfItems; // in above's collection 


我没有在这里放置 getter、setter 和构造函数/析构函数,所以不会太长。 在 Item.cpp 我有:

Item::Item(int number, std::string name)
:itemNumber(number), 
itemName(name), 
biggestBidder(NULL)

    // this->itemNumber= number;
    // this->itemName= name;
    // this->biggestBidder= NULL;


void Item::setbiggestBidder(Offer* const &offer)

    if (biggestBidder== NULL || biggestBidder->getAmount() < offer->getAmount())
    
        std::cout << "Address of offer in setbiggestBidder: " << offer << std::endl;
        std::cout << "Address of biggestBidder in setbiggestBidder: " << (biggestBidder) << std::endl;
        biggestBidder = offer;
        std::cout << "Address of biggestBidder in setbiggestBidder: " << (biggestBidder) << std::endl;
    
    else
    
    


Oferta *Lote::getBiggestBidder()


    std::cout << "Address of biggestBidder in getBiggestBidder(): " << this->biggestBidder << std::endl;
    if (this->biggestBidder == nullptr)
    
        std::cout << "biggestBidder IS NULL" << std::endl;
    
    else
    
        std::cout << "biggestBidder is NOT NULL" << std::endl;
    

    return biggestBidder;


现在,主要和问题:

Item l1(111, "BANANA");
Item l2(222, "MESA"); // this number 222 is just an ID for the item. It does nothing
Person p1("TheDude");
Offer of1(100, &p1);

// now put the item inside a vector and create an auction instance
std::vector<Item> item1;
collect.push_back(banana);
Auction coleccion1(collect, collect.size());


/*
Now we are ready. If I do this..
*/

std::cout << "Test with item outside vector" << std::endl;

std::cout << "Bidding $" << of1.getAmount() << " for item number " 
            << l2.getNumber() << ", " << l2.getItemName() << std::endl;

l2.setBiggestBidder(&of1); // amount 100
/*
If here I do 

l2.setBiggestBidder(&of2); // amount 200
l2.setBiggestBidder(&of1); // amount 100

At the bottom of the output, we get 200. It's all good.
*/
std::cout << l2.getBiggestBidder()->getAmount() << std::endl;

/* 
We get this output:
Test with item outside vector
Bidding $100 for item number 222, MESA
Address of offer in setbiggestBidder: 0x66fb20
Address of biggestBidder in setbiggestBidder: 0
Address of biggestBidder in setbiggestBidder: 0x66fb20
Address of biggestBidder in getBiggestBidder(): 0x66fb20
biggestBidder is NOT NULL
200 <-- l2.getBiggestBidder()->getAmount()
*/

// But if we try with the item inside the vector:

std::cout << "Bidding $" << of1.getAmount() << " for item number " 
                << coleccion1.getItemCollection().at(0).getNumber() << ", " 
                    << coleccion1.getItemCollection().at(0).getItemName() << std::endl;

/*
We get:
Test with item in vector
Bidding $100 for item number 111, BANANA
Address of offer in setbiggestBidder: 0x66fb10
Address of biggestBidder in setbiggestBidder: 0
Address of biggestBidder in setbiggestBidder: 0x66fb10
Address of biggestBidder in getBiggestBidder(): 0
biggestBidder IS NULL
0

and here is the issue.
*/

我真的不喜欢为一个我确信是关于一些非常基本的问题而写这么大的帖子,但我到处寻找,找不到任何解决这个问题的方法。 自从我偶然发现这一点以来已经有好几个星期了。

为什么如果我在方法 setBiggestBidder 上放置一个项目一切正常,但是当我将一个项目放在向量内时,更改不会在方法结束后继续存在?我该如何解决?

【问题讨论】:

请提供minimal reproducible example。你在哪里打电话给setBiggestBiddercoleccion1.getItemCollection().at(0)banana 是什么? 您知道collect.push_back(l2); 创建了一个副本吗?对l2 的每一次更改都不会应用于coleccion1.getItemCollection().at(0) 您要更新两个不同的对象。您更新了台面,但又期待香蕉上的变化?即使您尝试更新相同的项目,如上所述,您也会将副本放入向量中。我认为您需要花更多的时间来针对您遇到的确切问题提出问题。 @ThomasSablik 我没有意识到这一点。多亏了你,我才能解决它。在 Auction 类中,我将 std::vector 更改为 std::vector 并且成功了。谢谢大佬! @Taekahn 不。您正在混合这两个示例。一个显示代码如何与一个项目一起工作,另一个显示当项目位于向量内时发生(我遇到了问题)。当然,我不想在使用香蕉时修改台面。我想这只是一个基本的东西。我只是不知道向量创建了一个副本。现在,我该如何继续发帖?如果需要,我可以使用完整的代码更新它以复制错误,然后复制解决方案。但对于基本问题来说,这将是一篇非常大的帖子。 【参考方案1】:

collect.push_back(l2); 创建一个副本。 l2coleccion1.getItemCollection().at(0) 是两个不同的对象。如果您更改 l2 coleccion1.getItemCollection().at(0) 将不会更改。您可以在向量中存储一个指针。您应该记住,对象在函数结束时被销毁,并且向量包含一个悬空指针。

【讨论】:

以上是关于对对象成员、对象内部、向量内部所做的更改不会在方法结束后继续存在。 C++的主要内容,如果未能解决你的问题,请参考以下文章

推送到成员向量时的段错误

在连续的 java CompletionStages 之间对共享上下文对象所做的最新更改对于执行 lambda 的每个线程是不是始终可见

Java内部类:普通的成员内部类

java面向对象(上)--内部类

成员内部类

内部类的使用类型