C++;参照 最近4天开始学习C/C++背景下的C++。为了学习一门新的语言,我通常从重新实现不同的经典算法开始,尽可能地针对特定的语言
我来看看这段代码,它是一个无方向图中的DFS深度优先搜索。不过,从我读到的,最好通过C++中的引用传递参数。不幸的是,我不能完全理解引用的概念。每次我需要一个参考资料时,我都会感到困惑,我会用指针来思考。在我当前的代码中,我使用传递值 以下是代码(可能不是Cppthonic的应有代码):C++;参照 最近4天开始学习C/C++背景下的C++。为了学习一门新的语言,我通常从重新实现不同的经典算法开始,尽可能地针对特定的语言,c++,coding-style,reference,depth-first-search,C++,Coding Style,Reference,Depth First Search,我来看看这段代码,它是一个无方向图中的DFS深度优先搜索。不过,从我读到的,最好通过C++中的引用传递参数。不幸的是,我不能完全理解引用的概念。每次我需要一个参考资料时,我都会感到困惑,我会用指针来思考。在我当前的代码中,我使用传递值 以下是代码(可能不是Cppthonic的应有代码): #包括 #包括 #包括 #包括 #包括 #包括 使用名称空间std; 模板 无效utilShow(T元素); 模板 无效utilShow(T元素){ 沙发垫); 向量DFS(向量mat); /*从文件(fNam
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
模板
无效utilShow(T元素);
模板
无效utilShow(T元素){
沙发垫);
向量DFS(向量mat);
/*从文件(fName)读取矩阵*/
vectorgetMatrixFromFile(字符串fName)
{
无符号整数mDim;
ifstream-in(fName.c_str());
在>>mDim中;
向量mat(mDim,向量(mDim));
对于(int i=0;i>材料[i][j];
}
}
返回垫;
}
/*输出矩阵到标准输出*/
无效显示矩阵(向量<向量>矩阵){
向量<向量>::迭代器行;
对于(行=材料开始();行<材料结束();++行){
对于每个((*row.begin(),(*row.end(),utilShow));
沙发垫){
//访问时提供DFS的订单
堆栈节点堆栈;
//跟踪访问的节点
访问向量(mat.size(),false);
矢量结果;
nodeStack.push(0);
已访问[0]=真;
而(!nodeStack.empty()){
unsigned int-cIdx=nodeStack.top();
nodeStack.pop();
结果:推回(cIdx);
对于(int i=0;imat;
mat=getMatrixFromFile(“Ex04.in”);
向量dfsResult=DFS(mat);
cout pmatrix.resize(新尺寸*新尺寸);
}
模板
void SGraph::print()
{
对于(int i=0;ivoid utilShow(T&elem);
vectorgetMatrixFromFile(常量字符串和fName);
void showMatrix(向量&mat);
向量DFS(向量&mat);
如果可能的话,如果你不改变或者不打算改变你的方法体中对象的状态,让变量以常量的形式传递
<>我不会要求你在第一次尝试中包括所有C++结构,但是逐渐地不要让自己陷入抑郁状态。向量是最常用的STL容器。容器的使用取决于你的需要,而不是感觉到使用另一个容器。
容器的简要说明。
@谢谢你的编辑。
Vector并没有被过度使用,但由于其对简单对象的简单性而被更多地使用,而不是大型单一类对象。它类似于C风格的数组,但不是,有很多额外的算法。另外两个经常使用的是映射和列表。这可能是因为我工作的地方需要使用这些容器要通过引用传递,您通常会更改以下内容:
vector<unsigned int> DFS(vector< vector<short> > mat){
for_each((*row).begin(), (*row).end(), utilShow<short>);
例如:
std::copy(row->begin(), row->end(), std::ostream_iterator<short>(std::cout, " "));
请注意,这使用
operator()
进行索引,因此您可以使用m(x,y)
,而不是m(x,y)
,就像在BASIC或Fortran中一样。您可以通过某种方式重载operator[]
,如果您愿意的话,可以使用该符号,但这是(IMO)的大量额外工作在C++中,4天内,你做的很好。你已经使用了标准的容器、算法和编写自己的函数模板。我所看到的最缺乏的就是你的问题:需要通过引用/ const引用。< /P>
typedef vector<short> Row;
typedef vector<Row> SquareMatrix;
void showMatrix(const SquareMatrix& mat);
<>你通过值传递/返回C++对象时,你调用它的内容的一个深层拷贝。这根本不便宜,尤其是对于像你的矩阵类的东西。
首先让我们看看showMatrix。这个函数的目的是输出矩阵的内容。它需要副本吗?不。它需要更改矩阵中的任何内容吗?不,它的目的只是显示它。因此,我们希望通过常量引用传递矩阵
typedef vector<short> Row;
typedef vector<Row> SquareMatrix;
void showMatrix(const SquareMatrix& mat);
在这里按值返回SquareMatrix可能很昂贵(取决于编译器是否对这种情况应用返回值优化),按值传递字符串也是如此。对于C++0x,我们有右值引用来实现它,因此不必返回副本(出于与showMatrix相同的原因,我还修改了要通过const引用传入的字符串,我们不需要文件名的副本):
但是,如果您没有具有这些功能的编译器,那么一种常见的折衷方法是通过引用传入矩阵,并让函数填充它:
void getMatrixFromFile(const string& fName, SquareMatrix& out_matrix);
这并没有为客户机提供方便的语法(现在他们必须编写两行代码而不是一行),但它避免了持续的深度复制开销。还有一些方法可以解决这一问题,但这将在C++0x中过时
一个简单的经验法则:如果您有任何用户定义的类型(不是普通的旧数据类型),并且希望将其传递给函数:
std::copy(row->begin(), row->end(), std::ostream_iterator<short>(std::cout, " "));
for_each(dfsResult.begin(), dfsResult.end(), utilShow<unsigned int>);
std::copy(dfsResult.begin(), dfsResult.end(),
std::ostream_iterator<unsigned int>(std::cout, " "));
template <class T>
class matrix {
std::vector<T> data_;
size_t columns_;
public:
matrix(size_t rows, size_t columns) : columns_(columns), data_(rows * columns) {}
T &operator()(size_t row, size_t column) { return data[row * columns_ + column]; }
};
typedef vector<short> Row;
typedef vector<Row> SquareMatrix;
void showMatrix(const SquareMatrix& mat);
SquareMatrix getMatrixFromFile(string fName);
SquareMatrix&& getMatrixFromFile(const string& fName);
void getMatrixFromFile(const string& fName, SquareMatrix& out_matrix);
template <class T> void utilShow(T elem) { ... }
template <class T> void utilShow(const T &elem) { ... }
vector< vector<short> > getMatrixFromFile(const string &fName) { ... }
void showMatrix(const vector< vector<short> > &mat) { ... }
// Don't do this!
Foo& BrokenReturnRef() {
Foo f;
return f;
}
int main() {
Foo &f = BrokenReturnRef();
cout << f.bar();
}