最简单的传递参考需要什么?

时间:2015-06-16 21:19:42

标签: c++ g++

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

我试图弄清楚如何声明/定义一个非成员函数,该函数通过引用获取类对象的参数。我无法编译我的代码。我试图在下面的三个文件集中复制问题。

我使用eclipse(Luna)作为IDE,而后者又在Ubuntu 14.04上使用g ++。在这个集合中,我在MyTest.h中的非成员函数的声明中得到了一个神秘的编译错误,就像这样 "声明中的明确资格< void mytest :: printInt(ostream&,MyTest&)"

在我的真实世界示例中,我在此函数的模拟定义(非声明)中得到了一个非常类似的错误。

最初我认为它与我有关,阻止编译器创建默认构造函数和" MyTest&米"某种程度上需要一个默认的构造函数(尽管这对我来说完全没有任何意义)。但声明和定义默认构造函数并不会改变问题。

我做错了什么? 什么是定义非成员函数的正确方法,该函数将类对象作为参数by-reference)? 从中可以获得哪些更大的教训?

在文件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);
}

4 个答案:

答案 0 :(得分:6)

在printInt函数的声明和定义中删除&#34; mytest ::&#34;从功能名称。由于命名空间块,它已经在mytest命名空间中。

答案 1 :(得分:3)

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);
             ^~~~~~~~

vs GCC&#39>

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);

答案 2 :(得分:1)

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

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
}

答案 3 :(得分:0)

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

&#13;
&#13;
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)
&#13;
&#13;
&#13;