我在使用C ++实现我的图表时遇到了麻烦。
目前,我刚刚实现了Vertex和Edges,这里是类:
Vertex.h
#ifndef VERTEX_H_
#define VERTEX_H_
#include <string>
#include <iostream>
namespace MarcoGraphs {
enum class Colors {black, red};
class Vertex {
private:
std::string id;
int soglia, degree;
double peso;
Colors visited;
public:
Vertex(std::string id);
Vertex(const Vertex& param);
Vertex& operator=(const Vertex& param);
Vertex(Vertex&& param);
Vertex& operator=(Vertex&& param);
~Vertex();
bool operator!=(const Vertex& param);
bool operator==(const Vertex& param);
bool operator<(const Vertex& param);
std::string getId();
void setDegree(int degree);
int getDegree();
void incrementDegree();
void setSoglia(int soglia);
int getSoglia();
void setVisited(Colors mycolors);
Colors getVisited();
void setPeso(double peso);
double getPeso();
friend std::ostream& operator<<(std::ostream& out, const Vertex& a);
};
} /* namespace MarcoGraphs */
#endif /* VERTEX_H_ */
Vertex.cpp
#include "Vertex.h"
namespace MarcoGraphs {
Vertex::Vertex(std::string Id):
id(Id), soglia(0), degree(0), peso(0), visited(Colors::black){
}
Vertex::~Vertex() {
}
Vertex::Vertex(const Vertex& param):
id(param.id), soglia(param.soglia), degree(param.degree), peso(param.degree), visited(param.visited){
}
Vertex& Vertex::operator=(const Vertex& param){
id = param.id;
soglia = param.soglia;
degree = param.degree;
peso = param.peso;
visited = param.visited;
return *this;
}
Vertex::Vertex(Vertex&& param):
id(param.id), soglia(param.soglia), degree(param.degree), peso(param.degree), visited(param.visited){
param.id.clear();
}
Vertex& Vertex::operator=(Vertex&& param){
id = param.id;
param.id.clear();
soglia = param.soglia;
degree = param.degree;
peso = param.peso;
visited = param.visited;
return *this;
}
bool Vertex::operator!=(const Vertex& param){
return !(this->id==param.id);
}
bool Vertex::operator==(const Vertex& param){
return this->id==param.id;
}
bool Vertex::operator<(const Vertex& param){
return this->id<param.id;
}
std::string Vertex::getId(){
return id;
}
void Vertex::setDegree(int degree){
this->degree = degree;
}
int Vertex::getDegree(){
return degree;
}
void Vertex::incrementDegree(){
degree +=1;
}
void Vertex::setSoglia(int soglia){
this->soglia = soglia;
}
int Vertex::getSoglia(){
return soglia;
}
void Vertex::setVisited(Colors mycolor){
this->visited = mycolor;
}
Colors Vertex::getVisited(){
return visited;
}
void Vertex::setPeso(double peso){
this->peso = peso;
}
double Vertex::getPeso(){
return peso;
}
std::ostream& operator<<(std::ostream& out, const Vertex& a){
out << a.id << " " << a.peso << " " << a.soglia << "\n";
return out;
}
} /* namespace MarcoGraphs */
Edge.h
#ifndef EDGE_H_
#define EDGE_H_
#include <iostream>
#include "Vertex.h"
namespace MarcoGraphs {
class Edge {
private:
Vertex* v1;
Vertex* v2;
public:
Edge(Vertex v1, Vertex v2);
Edge(const Edge& param);
Edge& operator=(const Edge& param);
Edge(Edge&& param);
Edge& operator=(Edge&& param);
~Edge();
bool operator!=(const Edge& param);
bool operator==(const Edge& param);
bool operator<(const Edge& param);
Vertex* getV1();
Vertex* getV2();
friend std::ostream& operator<<(std::ostream& out, const Edge& a);
};
} /* namespace MarcoGraphs */
#endif /* EDGE_H_ */
Edge.cpp
#include "Edge.h"
namespace MarcoGraphs {
Edge::Edge(Vertex v1, Vertex v2):
v1(&v1), v2(&v2){
}
Edge::~Edge() {
}
Edge::Edge(const Edge& param):
v1(param.v1), v2(param.v2){
}
Edge& Edge::operator=(const Edge& param){
v1 = param.v1;
v2 = param.v2;
return *this;
}
Edge::Edge(Edge&& param):
v1(param.v1), v2(param.v2){
param.v1 = nullptr;
param.v2 = nullptr;
}
Edge& Edge::operator=(Edge&& param){
v1 = param.v1;
v2 = param.v2;
param.v1 = nullptr;
param.v2 = nullptr;
return *this;
}
bool Edge::operator!=(const Edge& param){
return !(*v1 == *(param.v1) && *v2 == *(param.v2));
}
bool Edge::operator==(const Edge& param){
return (*v1 == *(param.v1) && *v2 == *(param.v2));
}
bool Edge::operator<(const Edge& param){
if(*v1 != *(param.v1))
return *v1 < *(param.v1);
return *v2 < *(param.v2);
}
Vertex* Edge::getV1(){
return v1;
}
Vertex* Edge::getV2(){
return v2;
}
std::ostream& operator<<(std::ostream& out, const Edge& a){
out << a.v1->getId() << "," << a.v2->getId();
return out;
}
} /* namespace MarcoGraphs */
我尝试用这个小例子来测试这些类:
的main.cpp
#include "Vertex.h"
#include "Edge.h"
#include <iostream>
#include <set>
#include <algorithm>
#include <vector>
int main(){
MarcoGraphs::Vertex v1("Marco");
MarcoGraphs::Vertex v2("Stefano");
MarcoGraphs::Vertex v3("Giovanni");
std::vector<MarcoGraphs::Vertex> v(10);
v.push_back(v1);
v.push_back(v2);
v.push_back(v3);
return 0;
}
但是g ++给了我以下错误:
15:15:20 **** Incremental Build of configuration Debug for project Thesis ****
make all
Building file: ../Main.cpp
Invoking: Cross G++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -MMD -MP -MF"Main.d" -MT"Main.d" -o "Main.o" "../Main.cpp"
In file included from /usr/include/c++/4.9.0/bits/stl_tempbuf.h:60:0,
from /usr/include/c++/4.9.0/bits/stl_algo.h:62,
from /usr/include/c++/4.9.0/algorithm:62,
from ../Main.cpp:12:
/usr/include/c++/4.9.0/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = MarcoGraphs::Vertex; _Args = {}]’:
/usr/include/c++/4.9.0/bits/stl_uninitialized.h:515:43: required from ‘static void std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = MarcoGraphs::Vertex*; _Size = unsigned int; bool _TrivialValueType = false]’
/usr/include/c++/4.9.0/bits/stl_uninitialized.h:570:33: required from ‘void std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = MarcoGraphs::Vertex*; _Size = unsigned int]’
/usr/include/c++/4.9.0/bits/stl_uninitialized.h:631:50: required from ‘void std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with _ForwardIterator = MarcoGraphs::Vertex*; _Size = unsigned int; _Tp = MarcoGraphs::Vertex]’
/usr/include/c++/4.9.0/bits/stl_vector.h:1311:28: required from ‘void std::vector<_Tp, _Alloc>::_M_default_initialize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = MarcoGraphs::Vertex; _Alloc = std::allocator<MarcoGraphs::Vertex>; std::vector<_Tp, _Alloc>::size_type = unsigned int]’
/usr/include/c++/4.9.0/bits/stl_vector.h:279:34: required from ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = MarcoGraphs::Vertex; _Alloc = std::allocator<MarcoGraphs::Vertex>; std::vector<_Tp, _Alloc>::size_type = unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<MarcoGraphs::Vertex>]’
../Main.cpp:21:39: required from here
/usr/include/c++/4.9.0/bits/stl_construct.h:75:7: error: no matching function for call to ‘MarcoGraphs::Vertex::Vertex()’
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^
/usr/include/c++/4.9.0/bits/stl_construct.h:75:7: note: candidates are:
In file included from ../Main.cpp:8:0:
../Vertex.h:27:2: note: MarcoGraphs::Vertex::Vertex(MarcoGraphs::Vertex&&)
Vertex(Vertex&& param);
^
../Vertex.h:27:2: note: candidate expects 1 argument, 0 provided
../Vertex.h:25:2: note: MarcoGraphs::Vertex::Vertex(const MarcoGraphs::Vertex&)
Vertex(const Vertex& param);
^
../Vertex.h:25:2: note: candidate expects 1 argument, 0 provided
../Vertex.h:24:2: note: MarcoGraphs::Vertex::Vertex(std::string)
Vertex(std::string id);
^
../Vertex.h:24:2: note: candidate expects 1 argument, 0 provided
subdir.mk:24: recipe for target 'Main.o' failed
make: *** [Main.o] Error 1
你能帮助我吗?谢谢:)
答案 0 :(得分:0)
std::vector<MarcoGraphs::Vertex> v(10);
这会创建一个包含10个元素的向量,但为此它需要一个默认的构造函数,而这个元素是你没有的。
您可以使用reserve
来获得足够大的向量,或者将Vertex
传递给向量的构造函数。
在这里,有一些参考:
答案 1 :(得分:0)
Zsolt的回答是正确的,但也许并不能完全回答你的问题。所以我会尝试扩展它。
在C ++中,“默认构造函数”是一个不带参数的构造函数。在Vertex,Vertex()的情况下。
当您创建一个类并且没有定义任何构造函数时,C ++会为您创建一个默认构造函数,这可能就是您尚未遇到此问题的原因。对于Vertex,您已经创建了一些构造函数,因此编译器认为您已明确省略了默认构造函数。这通常是可取的,因为通常不存在有意义的默认值。
当您拨打电话时:
std::vector<MarcoGraphs::Vertex> v(10);
您告诉编译器要构建10个顶点的向量。由于您尚未提供分配器作为模板参数,因此它使用默认分配器,该分配器调用默认构造函数,该构造函数不存在。这就是您所看到的错误告诉您的内容(现在再次阅读它们,您应该能够理解它们的输出)。
在主循环中,您使用push_back将Vertexes添加到向量中,因此实际上不需要构造10个默认顶点。您有几种选择:
保留内存实际上是一种优化,当您知道向量将存储多少个对象并且不希望使用push_back命令动态重新分配内存时,这非常有用。对于你的具体程序,我认为这是一个不成熟的优化,只会删除“(10)”。