C++ 无法在 class 的 class 中使用 setter 修改私有变量
C++ can't modify private variable with setter in a class of class
我知道 setter 函数是 C++ 中的基本函数,但我似乎无法正确创建一个函数。
我有一个 class、Graph
,其中包含另一个 class、Vertex
。
在 main
中,我实例化一个 Graph
类型的对象并使用该对象读取一个文件,该文件将 Vertex
类型的对象添加到 Graph
.
问题是,之后当我尝试打印 Graph
对象时,一切似乎都是空的。我认为我在滥用指针或引用。
你能解释一下为什么我有 6 个 Vertex
对象,但它们都是空的吗? (我试图将 Vertex
的 vector
更改为 vector*
但这并没有解决我的问题,我想我还是丢失了 Vertex
对象...)?
Main.cpp
int main(int argc, char *argv[]){
Graph g = Graph();
g.readDotFile("graph.dot");
std::cout << g << std::endl;
return 0;
}
Graph.hpp
class Graph{
private:
class Vertex{
public:
Vertex();
Vertex(std::string name);
Vertex(Vertex const& v);
~Vertex();
const std::string& getIdVertex()const;
friend std::ostream& operator<<(std::ostream &os, Vertex const& v);
void printVertex(std::ostream &os)const;
void setStartToStart(const std::string& name);
private:
std::string idVertex;
std::vector<std::string> startToStart;
};
public:
Graph();
void readDotFile(std::string dotFile); // Graph from a dot file
Graph(Graph const& g);
~Graph();
void addVertex(Vertex& v);
void addEdge(int typeOfEdge, std::string name1, std::string name2);
const std::vector<Graph::Vertex>& getVertices()const;
friend std::ostream& operator<<(std::ostream &os, Graph const& g);
friend std::ostream& operator<<(std::ostream &os, Vertex const& v);
void printGraph(std::ostream &os)const;
private:
std::vector<Vertex> vertices;
};
Graph.cpp
#include "graph.hpp"
Graph::Vertex::Vertex(){}
Graph::Vertex::Vertex(std::string name){
idVertex = name;
}
Graph::Vertex::Vertex(Graph::Vertex const& v){}
Graph::Vertex::~Vertex(){}
const std::string& Graph::Vertex::getIdVertex()const{ return idVertex; }
void Graph::Vertex::setStartToStart(const std::string& v){
startToStart.push_back(v);
}
Graph::Graph(){}
Graph::Graph(Graph const& g){}
Graph::~Graph(){}
const std::vector<Graph::Vertex>& Graph::getVertices()const{ return vertices; }
void Graph::readDotFile(std::string file){
std::ifstream dotFileIn(file.c_str());
std::string line;
while (getline(dotFileIn, line)){
// Read the file, the problem don't come from here, I just don't show the code
addEdge(1, "origin", "destination");
}
}
}
void Graph::addVertex(Graph::Vertex& v){ // Before create, verify the vertex does not exist
vertices.push_back(v);
}
void Graph::addEdge(int typeOfEdge, std::string name1, std::string name2){
Graph::Vertex v1 = Graph::Vertex(name1);
addVertex(v1);
Graph::Vertex v2 = Graph::Vertex(name2);
addVertex(v2);
v1.setStartToStart(name2);
}
std::ostream& operator<<(std::ostream &os, Graph const& g)
{
g.printGraph(os);
return os;
}
void Graph::printGraph(std::ostream &os)const{
for (unsigned int i = 0; i < vertices.size(); ++i){
vertices[i].printVertex(os);
}
}
std::ostream& operator<<(std::ostream &os, Graph::Vertex const& v)
{
v.printVertex(os);
return os;
}
void Graph::Vertex::printVertex(std::ostream &os)const{
os << " vertex : " << idVertex << "\t";
for (unsigned int i = 0; i < startToStart.size(); ++i){
os << "startToStart: " << startToStart[i] << "\t";
}
}
}
您的 Graph
class 定义了具有空主体的构造函数,因此这些成员默认已初始化。
main()
中的行
Graph g = Graph();
使用默认构造函数创建一个默认构造的Graph
(暂时)。然后它使用复制构造函数将该临时文件复制到 g
.
Graph
的默认构造函数和复制构造函数均保留对象的默认初始化。
解决方案是确保所有构造函数适当地初始化他们正在创建的对象,而不是假设值将被复制。
(以上假定没有编译器优化,例如省略临时变量)。
这里的问题是 addVertex(v1);
会将 v1
的 copy 添加到您的 vertices
成员向量中,因为这是 vector::push_back
做。然后你继续修改 v1
(原来的),但是这个改变不会反映在你的成员变量上(v2
也是如此)。您应该将两个调用移至 addEdge
函数末尾的 addVertex
。
我知道 setter 函数是 C++ 中的基本函数,但我似乎无法正确创建一个函数。
我有一个 class、Graph
,其中包含另一个 class、Vertex
。
在 main
中,我实例化一个 Graph
类型的对象并使用该对象读取一个文件,该文件将 Vertex
类型的对象添加到 Graph
.
问题是,之后当我尝试打印 Graph
对象时,一切似乎都是空的。我认为我在滥用指针或引用。
你能解释一下为什么我有 6 个 Vertex
对象,但它们都是空的吗? (我试图将 Vertex
的 vector
更改为 vector*
但这并没有解决我的问题,我想我还是丢失了 Vertex
对象...)?
Main.cpp
int main(int argc, char *argv[]){
Graph g = Graph();
g.readDotFile("graph.dot");
std::cout << g << std::endl;
return 0;
}
Graph.hpp
class Graph{
private:
class Vertex{
public:
Vertex();
Vertex(std::string name);
Vertex(Vertex const& v);
~Vertex();
const std::string& getIdVertex()const;
friend std::ostream& operator<<(std::ostream &os, Vertex const& v);
void printVertex(std::ostream &os)const;
void setStartToStart(const std::string& name);
private:
std::string idVertex;
std::vector<std::string> startToStart;
};
public:
Graph();
void readDotFile(std::string dotFile); // Graph from a dot file
Graph(Graph const& g);
~Graph();
void addVertex(Vertex& v);
void addEdge(int typeOfEdge, std::string name1, std::string name2);
const std::vector<Graph::Vertex>& getVertices()const;
friend std::ostream& operator<<(std::ostream &os, Graph const& g);
friend std::ostream& operator<<(std::ostream &os, Vertex const& v);
void printGraph(std::ostream &os)const;
private:
std::vector<Vertex> vertices;
};
Graph.cpp
#include "graph.hpp"
Graph::Vertex::Vertex(){}
Graph::Vertex::Vertex(std::string name){
idVertex = name;
}
Graph::Vertex::Vertex(Graph::Vertex const& v){}
Graph::Vertex::~Vertex(){}
const std::string& Graph::Vertex::getIdVertex()const{ return idVertex; }
void Graph::Vertex::setStartToStart(const std::string& v){
startToStart.push_back(v);
}
Graph::Graph(){}
Graph::Graph(Graph const& g){}
Graph::~Graph(){}
const std::vector<Graph::Vertex>& Graph::getVertices()const{ return vertices; }
void Graph::readDotFile(std::string file){
std::ifstream dotFileIn(file.c_str());
std::string line;
while (getline(dotFileIn, line)){
// Read the file, the problem don't come from here, I just don't show the code
addEdge(1, "origin", "destination");
}
}
}
void Graph::addVertex(Graph::Vertex& v){ // Before create, verify the vertex does not exist
vertices.push_back(v);
}
void Graph::addEdge(int typeOfEdge, std::string name1, std::string name2){
Graph::Vertex v1 = Graph::Vertex(name1);
addVertex(v1);
Graph::Vertex v2 = Graph::Vertex(name2);
addVertex(v2);
v1.setStartToStart(name2);
}
std::ostream& operator<<(std::ostream &os, Graph const& g)
{
g.printGraph(os);
return os;
}
void Graph::printGraph(std::ostream &os)const{
for (unsigned int i = 0; i < vertices.size(); ++i){
vertices[i].printVertex(os);
}
}
std::ostream& operator<<(std::ostream &os, Graph::Vertex const& v)
{
v.printVertex(os);
return os;
}
void Graph::Vertex::printVertex(std::ostream &os)const{
os << " vertex : " << idVertex << "\t";
for (unsigned int i = 0; i < startToStart.size(); ++i){
os << "startToStart: " << startToStart[i] << "\t";
}
}
}
您的 Graph
class 定义了具有空主体的构造函数,因此这些成员默认已初始化。
main()
Graph g = Graph();
使用默认构造函数创建一个默认构造的Graph
(暂时)。然后它使用复制构造函数将该临时文件复制到 g
.
Graph
的默认构造函数和复制构造函数均保留对象的默认初始化。
解决方案是确保所有构造函数适当地初始化他们正在创建的对象,而不是假设值将被复制。
(以上假定没有编译器优化,例如省略临时变量)。
这里的问题是 addVertex(v1);
会将 v1
的 copy 添加到您的 vertices
成员向量中,因为这是 vector::push_back
做。然后你继续修改 v1
(原来的),但是这个改变不会反映在你的成员变量上(v2
也是如此)。您应该将两个调用移至 addEdge
函数末尾的 addVertex
。