- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我有一个自定义类“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/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!