Hi, On Sun, Nov 07, 2010 at 12:13:29PM -0800, denilsson31 wrote: > > First of all, thank you, Axel for answering. > > Yes, this was my first guess regarding the compiler's message. > > But, see again my trivial example. It's exactly the same design. Try > compiling. And it's troublesome. I think we misunderstand each other: Your trivial example has a fundamental difference -- the missing "virtual": a) in the real example, you derive "TemporaryDbFile" from "QFile" and "dbFile", where: - QFile has a virtual function "close()" returning "void" - dbFile has a virtual function "close()" returning "int" (even a pure one) Now, when you define a function "close()" in the derived class "TemporaryDbFile" this function: - has to return "void", as it overrides the virtual function from QFile - has to return "int", as it overrides the virtual function from dbFile ==> this CAN'T work ;-) b) in the trivial example, you derive "C" from "A" and "B", where: - "A" has a NON-virtual function "close()" returning "void" - "B" has a virtual function "close()" returning "int" (even a pure one) Now, when you define a function "close()" in the derived class "C", this function: - HIDES "A::close()" (as A::close is NOT Virtual) - has to return "int", as it overrides the virtual function from "B" ==> everything works. Try the following code to see what I mean -- the function "A::close()" is NOT overridden by "C::close()", the function "B::close()" IS: #include <iostream> class A { public: void close() { std::cout << "A" << std::endl;} }; class B { public: virtual int close() = 0; }; class C :public A, public B { public: int close() { std::cout << "C" << std::endl; return 0; } }; int main() { C c; A &a = c; B &b = c; std::cout << "Use a:"; a.close(); std::cout << "Use b:"; b.close(); std::cout << "Use c:"; c.close(); } When calling "b.close" or "c.close()", the code outputs "C" (as expected for virtual functions). However, when calling "a.close()", it outputs "A" (as A::close is NO virtual function!). a.close() returns "void", b.close() and c.close() return "int" If you would change the "void close()" in class A also to a virtual function, the code won't compile anymore. So I think the only solution will be something like the trick suggested by Dario Axel > > > Axel Freyn wrote: > > > > Hi, > > > > I think your code is no valid C++: > > On Sun, Nov 07, 2010 at 09:17:56AM -0800, denilsson31 wrote: > >> Hi, > >> > >> I'm developping in Qt and I'm experiencing some compilation errors I > >> can't > >> correct. > >> I define a class, TemporaryDbFile that is a QFile's and dbFile's > >> derivate. > >> > >> QFile is defined like this: > > (I corrected some typos in your code) > >> > >> class QFile { > >> public: > >> virtual void close(); > >> }; > >> class dbFile { > >> public: > >> virtual int close() = 0; > >> }; > >> > >> So, TemporaryDbFile has the duty to implement dbFile's interface with > >> QTemporaryFile (derivated from QFile) : > >> > >> class TemporaryDbFile :public QFile, public dbFile > >> { > >> int close() { } > >> }; > >> > >> But in this nice picture, there is a sand grain : the gcc compiler 4.4.0. > >> He tells, mockingly : > >> > >> TemporaryDbFile.h:42:error: conflicting return type specified for > >> 'virtual > >> int TemporaryDbFile::close()' > >> C:\Qt\2010.03\qt\include\QtCore\..\..\src\corelib\io\qfile.h:148:error: > >> overriding 'virtual void QFile::close()' > > The critical point is: The base-class "QFile" defines "close" to be a > > VIRTUAL function! So, when you define "int close()" in the derived > > class, C++ believes you want to override the virtual function defined in > > the base classes: those defined in QFile AND in dbFile. However, > > "close()" in QFile has a different return type as the one defined in > > TemporaryDbFile ==> Thus the error message from the compiler. > >> > >> Nevertheless, this minimalist sample, representative of my concern is > >> accepted by the compiler: > >> > >> class A { > >> public: > >> void close() {} > >> }; > >> > >> class B { > >> public: > >> virtual int close() = 0; > >> }; > >> > >> > >> class C :public A, public B > >> { > >> public: > >> int close() > >> { > >> A::close(); > >> return 0; > >> } > >> }; > > In this example, you ommitted the "virtual" in class A, thus defining in > > class A a non-virtual function. If you define now "int close()" in class > > C, this new function will override the non-virtual function "void > > close()" from class A (which is perfectly fine). > > > > So, to state it differently: > > 1) If you create a "TemporaryDbFile" and access it as QFile: > > QFile &q = TemporaryDbFile(); > > q.close() > > Here, the caller expects that "close" returns "void"; however > > (QFile::close() beeing a virtual function) the code will call > > "TemporaryDbFile::close()" which returns an integer ==> that's why the > > compiler won't compile this code. > > > > 2) if you create a "C" and access it as A: > > A& a = C(); > > a.close(); > > Here, as "A::close()" is NO virtual function, the code will just execute > > "A::close()" (which returns void), completely ignoring the "C::close()" > > returning an int ==> everything works fine and the code compiles. > > > > So, I think you have to decide what the code shall do -- and then > > correct your code > > > > (At least, thats what I think -- Maybe I'm wrong with my interpretation > > of the virtual functions mechanisms here -- I don't have a C++-Standard > > handy...) > > > > > > HTH, > > > > Axel > > > >