gpt4 book ai didi

自定义类构造函数中的 C++ 指针赋值

转载 作者:行者123 更新时间:2023-11-28 08:22:50 25 4
gpt4 key购买 nike

所以我有一个自定义类“Book”,它有一堆成员变量,其中有另一个自定义类“Review”的 vector 和一个指向该 vector 的指针,因为我需要通过函数传递它调用驱动程序。驱动程序从文本文件中读取每本书的详细信息(如标题、作者、出版日期等),并将其插入到一个临时“书籍”对象中,然后将其添加到由驱动程序维护的 Books vector 中。这是从文件中读取的代码:

ifstream file("books.txt");
string line;
if(file.is_open())
{
while(!file.eof())
{
Book buffBook;
getline(file, line);
buffBook.setTitle(line);
getline(file, line);
buffBook.setAuthor(line);
getline(file, line);
buffBook.setPubDate(line);
getline(file, line);
buffBook.setIsbn(line);
getline(file, line);
buffBook.setCategory(line);
getline(file, line);
buffBook.setFormat(line);
getline(file, line);
buffBook.setSynopsis(line);
vectBooks.push_back(buffBook);
}
}

else
cout<<"File not found(1)!"<<endl;

file.close();

这是在 int main() 函数中运行的。
驱动程序的功能之一是添加评论,它从用户那里获取数据并将其插入到临时的“评论”对象中。然后将该对象传递给插入到相应书籍的评论 vector 中。以下是 addReview() 函数的代码:

void addReview()
{
string name = "";
string title;
Book rTemp;
cin.ignore();
cout<<"Which book would you like to rate (Title)?: ";
getline(cin, name);
name = toLow(name);
Review r;
string re, user;
int ra;
cout<<"Username (Full Name): ";
getline(cin, user);
string fname = user.substr(0, user.find_first_of(' '));
string lname = user.substr( user.find_first_of(' ') + 1, user.size());
r.setUsrFName(fname);
r.setUsrLName(lname);
cout<<"Enter rating (1-5):";
cin>>ra;
r.setRating(ra);
cout<<"Enter a short textual review: ";
cin.ignore();
getline(cin, re);
r.setReview(re);
for(unsigned int i = 0; i < vectBooks.size(); i++)
{
title = toLow(vectBooks[i].getTitle());
if(title.find(name) != string::npos)
{
vectBooks[i].getReviews()->push_back(r);
}
}
}

现在的问题是,如果我添加评论,它会为所有书籍添加评论。换句话说,当我获取任何书籍的书籍信息时,评论会显示在所有书籍上。我认为这是指针的问题,因为似乎所有评论都存储在同一个 vector 中。我不确定我在哪里搞砸了,但我有一种感觉,指针在某个地方。任何帮助表示赞赏。

谢谢

更新

这个问题的标题是我在 Book 类的构造函数中将指针赋值给 Reviews vector ,这两个是成员变量。构造函数代码如下:

Book::Book()
{
pointRev = &vectReviews;
}

更新 2

这是 Book 类和支持类的代码:

书.h

#ifndef BOOK_H_
#define BOOK_H_

#include <string>
#include <iostream>
#include <vector>
#include "review.h"

using namespace std;

class Book
{
private:
string title;
string author;
string pubDate;
string isbn;
string category;
string format;
string synopsis;
vector<Review> vectReviews;
vector<Review>* pointRev;
public:
Book::Book() : pointRev(&vectReviews) {};
string getAuthor() const;
string getCategory() const;
string getFormat() const;
string getIsbn() const;
string getPubDate() const;
string getSynopsis() const;
string getTitle() const;
vector<Review>* getReviews();
void setAuthor(string author);
void setCategory(string category);
void setFormat(string format);
void setIsbn(string isbn);
void setPubDate(string pubDate);
void setSynopsis(string synopsis);
void setTitle(string title);

friend ostream& operator <<(ostream& out, Book& book);
vector<Review> *getPointRev() const;
vector<Review> getVectReviews() const;
void setPointRev(vector<Review> *pointRev);
void setVectReviews(vector<Review> vectReviews);


};

#endif /* BOOK_H_ */

书。 cpp

#include "book.h"
string Book::getAuthor() const
{
return author;
}

string Book::getCategory() const
{
return category;
}

string Book::getFormat() const
{
return format;
}

string Book::getIsbn() const
{
return isbn;
}

string Book::getPubDate() const
{
return pubDate;
}

string Book::getSynopsis() const
{
return synopsis;
}

string Book::getTitle() const
{
return title;
}

void Book::setAuthor(string author)
{
this->author = author;
}

void Book::setCategory(string category)
{
this->category = category;
}

void Book::setFormat(string format)
{
this->format = format;
}

void Book::setIsbn(string isbn)
{
this->isbn = isbn;
}

void Book::setPubDate(string pubDate)
{
this->pubDate = pubDate;
}

void Book::setSynopsis(string synopsis)
{
this->synopsis = synopsis;
}

void Book::setTitle(string title)
{
this->title = title;
}

vector<Review> *Book::getPointRev() const
{
return pointRev;
}

vector<Review> Book::getVectReviews() const
{
return vectReviews;
}

void Book::setPointRev(vector<Review> *pointRev)
{
this->pointRev = pointRev;
}

void Book::setVectReviews(vector<Review> vectReviews)
{
this->vectReviews = vectReviews;
}

vector<Review>* Book::getReviews()
{
return pointRev;
}


ostream& operator <<(ostream& out, Book& book)
{
out<<"\nTitle: "<<book.getTitle()<<endl;
out<<"Author: "<<book.getAuthor()<<endl;
out<<"Publish Date: "<<book.getPubDate()<<endl;
out<<"ISBN: "<<book.getIsbn()<<endl;
out<<"Category: "<<book.getCategory()<<endl;
out<<"Format: "<<book.getFormat()<<endl;
out<<"Synopsis: "<<book.getSynopsis()<<endl;
cout<<"\n--- Reviews ---"<<endl;
// vector<Review>* revs = book.getReviews();
for(unsigned int h = 0; h < book.getReviews()->size(); h++)
{
cout<<"Review by: "<<book.getReviews()->at(h).getUsrFName()<<" "<<book.getReviews()->at(h).getUsrLName()<<endl;
cout<<"Rating: "<<book.getReviews()->at(h).getRating()<<endl;
cout<<"Review: "<<book.getReviews()->at(h).getReview()<<endl;
}

return out;
}

review.h

#ifndef REVIEW_H_
#define REVIEW_H_

#include <string>

using namespace std;

class Review
{
private:
int rating;
string review;
string usrFName;
string usrLName;
public:
int getRating() const;
string getReview() const;
void setRating(int rating);
void setReview(string review);
string getUsrFName() const;
string getUsrLName() const;
void setUsrFName(string usrFName);
void setUsrLName(string usrLName);
};

#endif /* REVIEW_H_ */

评论.cpp

#include "review.h"



int Review::getRating() const
{
return rating;
}

string Review::getReview() const
{
return review;
}


void Review::setRating(int rating)
{
this->rating = rating;
}

string Review::getUsrFName() const
{
return usrFName;
}

string Review::getUsrLName() const
{
return usrLName;
}

void Review::setUsrFName(string usrFName)
{
this->usrFName = usrFName;
}

void Review::setUsrLName(string usrLName)
{
this->usrLName = usrLName;
}

void Review::setReview(string review)
{
this->review = review;
}

最佳答案

从您描述的行为来看,复制构造函数正在运行并生成指向同一 vector 的两个对象。 push_back 确实使用了复制构造函数。

但您的第一个代码片段不会复制同一本 Book,而是在每次循环迭代时创建一个新的 Book(然后复制到vectBooks.

如果 Book 没有正确的用户定义的复制构造函数,那么您就没有正确管理 pointRev。从观察到的行为来看,我相信您有一个释放 pointRev 的析构函数,然后 vectBooks 中的拷贝留下一个悬空指针。根据标准,这之后的一切都属于未定义行为的范畴,意思是“任何事情都可能发生”然后下一本Book恰好重用了相同的内存区域,所以所有的Book 的实例最终在野指针中具有相同的值。然后更新任何一个都会改变所有 Book 实例看到的 vector (它甚至不再存在)。

你为什么要使用指向 std::vector 的指针?将 vector 作为直接数据成员放入类中要好得多,这样编译器就可以自动构造、复制和销毁它,而无需您的额外帮助。


当然,您完全有可能将 vectReviews 设置为全局变量,然后每本书都指向同一个实例。这样一来评论会同时出现在所有书籍中,因为它们共享您要添加评论的 vector 。

关于自定义类构造函数中的 C++ 指针赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5163833/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com