What is needed for the simplest link transfer?
I am very new to C ++. I like Java and Python and I try to do a quick start in C ++.
I'm trying to figure out how to declare / define a non-member function that takes an argument to reference a class object. I am unable to compile my code. I tried to reproduce the problem in the set of 3 files below.
I am using eclipse (Luna) as IDE, which in turn uses g ++ on Ubuntu 14.04. In this set, I get a cryptic compilation error in the non-member function declaration in MyTest.h that looks like "Explicit qualification in the declaration" void mytest :: printInt (ostream &, MyTest &) "
In my real-life example, I get a very similar error in defining (not declaring) an analog of this function.
I originally thought it was because I was not letting the compiler create a default constructor, and "MyTest & m" somehow needs a default constructor (although it didn't make any sense to me at all). But declaring and defining the default constructor doesn't change the problem.
What am I doing wrong? What is the correct way to define a non-member function that takes class objects as arguments by reference)? What are some of the bigger lessons from this?
In the file 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_ */
In the file MyTest.cpp
#include "MyTest.h"
namespace mytest {
void mytest::printInt(ostream& os, MyTest& m){
os << m.getA();
}
} /* namespace mytest */
And finally, the file to run, 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);
}
source to share
You shouldn't add a namespace qualifier from a namespace:
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();
}
Then:
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
}
source to share
B MyTest.h
and MyTest.cpp
replace
void mytest::printInt(ostream& os, mytest::MyTest& m)
from
void printInt(ostream& os, mytest::MyTest& m)
mytest::
not required because your declaration and definition are already inside the namespace block.
On the side of the note, I recommend using Clang for (sometimes) a bit less critical error messages. Klang says about this line:
./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
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);
source to share
Yoohoo, I got it. My Makefile was bad as Galik pointed out. Adding MyTest.o to the OBJS list fixed it.
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)
source to share