最简单的传递引用需要什么?

What is needed for the simplest pass-by-reference?

我是 C++ 的新手。我对 Java 和 Python 很满意,我正在尝试快速入门 C++。

我想弄清楚如何 declare/define 一个非成员函数,该函数通过引用将参数传递给 class 对象。我无法编译我的代码。我试图在下面的三个文件集中复制问题。

我将 eclipse (Luna) 用作 IDE,后者又在 Ubuntu 14.04 上使用 g++。在这个集合中,我在 MyTest.h 中的非成员函数声明中遇到了一个神秘的编译错误,就像 "explicit qualification in the declaration of 'void mytest::printInt(ostream&, MyTest&)"

在我真实世界的例子中,我在这个函数的类似物的定义(不是声明)中遇到了一个非常相似的错误。

最初我认为这与我阻止编译器创建默认构造函数和 "MyTest& m" 以某种方式需要默认构造函数有关(尽管这对我来说完全没有任何意义)。但是声明和定义默认构造函数并不能改变问题。

我做错了什么? 定义将 class 对象作为引用参数的非成员函数的正确方法是什么? 从中可以吸取哪些更大的教训?

在文件 Mytest.h 中:

#ifndef MYTEST_H_
#define MYTEST_H_

#include<iostream>

namespace mytest {

using std::ostream;

class MyTest {
public:
    MyTest(int a) : a(a) {}
    int getA() { return a; }
private:
    int a;
};

void mytest::printInt(ostream& os, mytest::MyTest& m);

} /* namespace mytest */

#endif /* MYTEST_H_ */

在文件中 MyTest.cpp

#include "MyTest.h"

namespace mytest {

void mytest::printInt(ostream& os, MyTest& m){
    os << m.getA();
}

} /* namespace mytest */

最后一个文件给运行他们,Test.cpp:

#include "MyTest.h"

using mytest::MyTest;
using std::cout;
using std::endl;

int main(void) {
    MyTest a = MyTest(1);
    mytest::printInt(cout, a);
}

在 printInt 函数的声明和定义中,从函数名中删除 "mytest::"。由于命名空间块,它已经在 mytest 命名空间中。

您不应从命名空间中添加命名空间限定符:

namespace mytest {

using std::ostream;

class MyTest {
public:
    MyTest(int a) : a(a) {}
    int getA() { return a; }
private:
    int a;
};

// no namespace qualifier here
void printInt(ostream& os, MyTest& m);

} /* namespace mytest */


namespace mytest {

// no namespace qualifier here
void printInt(ostream& os, MyTest& m){
    os << m.getA();
}

然后:

using mytest::MyTest;
using std::cout;
using std::endl;

int main(void) {
    MyTest a = MyTest(1);
    mytest::printInt(cout, a); // now use the namespace qualifier
}

MyTest.hMyTest.cpp中替换

void mytest::printInt(ostream& os, mytest::MyTest& m)

void printInt(ostream& os, mytest::MyTest& m)

mytest:: 不需要,因为您的声明和定义已经在命名空间块中。

附带说明一下,我建议(有时)使用 Clang 来处理不那么神秘的错误消息。 Clang 对这一行说:

./MyTest.h:18:14: error: out-of-line declaration of 'printInt' does not match any declaration in namespace 'mytest'
void mytest::printInt(ostream& os, mytest::MyTest& m);
             ^~~~~~~~

与 GCC 的

MyTest.h:18:53: error: explicit qualification in declaration of ‘void mytest::printInt(std::ostream&, mytest::MyTest&)’
 void mytest::printInt(ostream& os, mytest::MyTest& m);

哟吼,我明白了。正如 Galik 所指出的,我的 Makefile 很糟糕。将 MyTest.o 添加到 OBJS 列表修复了它。

CXXFLAGS = -O2 -g -Wall -fmessage-length=0

OBJS =  Test.o MyTest.o

LIBS =

TARGET = Test

$(TARGET): $(OBJS)
 $(CXX) -o $(TARGET) $(OBJS) $(LIBS)

all: $(TARGET)

clean:
 rm -f $(OBJS) $(TARGET)