|
You will not get the result you hope for if you call a virtual function from a constructor. It's because the virtual table isn't fully set up until the contructor call returns. There is nothing you can do about it. Try something like:
class Base {
public:
base(){}
virtual void Init() { a(); b();}
};
...or make an object factory class which does just that.
|
|
|
|
|
Thank you,
I implemented your suggestion. Now it's working.
|
|
|
|
|
Oh.. really good one.
Nice talking to you.
If you judge people, you have no time to love them. -- Mother Teresa
|
|
|
|
|
Even after you've implemented toxcct's solution, calling virtual functions in a constructor is bad practice and a recipe for disaster. Consider the following code:
#include "stdafx.h"
#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
LogClass();
}
virtual LogClass()
{
cout << "Base" << endl;
}
};
class Derived : public Base
{
public:
virtual LogClass()
{
cout << "Derived" << endl;
}
};
int main(int argc, char* argv[])
{
Derived d;
d.LogClass();
return 0;
}
The output of this program is:
Base
Derived
And not, as you may expect:
Derived
Derived
There are languages where the second is produced in code like this (like C# I believe); they've got it wrong. The reason for this behaviour is that the constructor of a class builds the environment the member functions of that class require; they setup the classes’ invariants. For example for a logging class it may open a file and set a member variable to the file handle; all the classes' functions expect it. This means it is wrong to call a classes member functions before its constructor has been called. In our example the class Derived is only partially constructed; the Derived constructor hasn't been called yet so we can't call its member functions; the virtual function call mechanism makes sure this can't happen accidently.
Steve
|
|
|
|
|
The compiler adds a default constructor to a class that does contain any constructor. Here also the constructor adds a default constructor to the class Derived. In inheritance, when th e derived class object is created,
first the base class constructor will be called and then the derived class construcot will be called. Here the base class constructor involves a call to the local LogClass() hence first 'Base' will be printed and then d.LogClass() prints 'Derived'.
|
|
|
|
|
Hi,
Im pretty new to C++.. been messing with the standard library for a while..
but im in need of some help here.. i apologise i dont really have decent code
to show.. as i said im new... Anyway.. the problem is im getting some strange imput from the command line console some after the accepting socket...
heres what i get...
C:\>winsock
Listening on Socket
USER test
q▲∟¼q↔¼q^↔¼qzv½qPëV
PASS test
qi ¼q2è½q►=½q╡↔¼qµ@½qUSER test
q▲∟¼q↔¼q^↔¼qzv½qPëV
Listening on Socket
Yeah.. my computer beeps and everything.. some strange mating call of FTP i presume... basically i was wondering what that is.. and how to recieve data in only regular text format after sending data... so i can process the login and other ftp commands...
heres what i get in the client so far for this code...
[R] Connecting to 127.0.0.1 -> IP=127.0.0.1 PORT=21
[R] Connected to 127.0.0.1
[R] 220 Welcome to my Custom FTP
[R] USER test
[R] 331 Password Required
[R] PASS (hidden)
[R] 230 Welcome to my Custom FTP.
[R] SYST
[R] QUIT
please have a look at the code... im using devc++ and it does compile ok...
without further wait.. heres what ive got so far...
#include <winsock2.h>
#include <string.h>
#include <iostream.h>
using namespace std;
int accept(SOCKET AcceptSocket, SOCKET ListenSocket);
int main() {
int sk;
WSAData wsaData;
WORD wVersionRequested;
wVersionRequested=MAKEWORD(2, 0);
WSAStartup( wVersionRequested, &wsaData );
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(21);
int test;
while(1){
SOCKET ListenSocket;
ListenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (bind( ListenSocket,
(SOCKADDR*) &service,
sizeof(service)) == SOCKET_ERROR) {
cout << "bind() failed.\n";
closesocket(ListenSocket);
return 1;
}
cout << "Listening on Socket\n";
SOCKET AcceptSocket;
sk=listen( ListenSocket, 10 );
AcceptSocket = accept( ListenSocket, NULL, NULL );
test=accept(AcceptSocket, ListenSocket);
#ifdef WIN32
Sleep( 5000 );
#endif
if(test==2){break;}
}
WSACleanup(); return 0;
}
int accept (SOCKET AcceptSocket, SOCKET ListenSocket) {
int bytesSent;
int bytesRecv;
int test;
char sendbuf[1024] = "220 Welcome to my Custom FTP\n";
char* recvbuf = "";
char user[32];
char pass[32];
bytesSent=send( AcceptSocket, sendbuf, strlen(sendbuf), 0 );
while(1) { bytesRecv=recv( AcceptSocket, user, strlen(user), 0 ); break;}
#ifdef WIN32
Sleep( 50 );
#endif
char newsendbuf[1024]="331 Password Required\n";
bytesSent=send( AcceptSocket, newsendbuf, strlen(newsendbuf), 0 );
while(1) { bytesRecv=recv( AcceptSocket, pass, strlen(pass), 0 ); break;}
//HERE IS WHERE I COUT USER AND PASS and wierd result
cout << user << "\n" << pass << "\n";
Sleep( 50 );
char newendbuf[1024]="230 Welcome to my Custom FTP.\n";
bytesSent=send( AcceptSocket, newendbuf, strlen(newendbuf), 0 );
Sleep( 50 );
closesocket(ListenSocket);
}
// ANY HELP IS APPRECIATED THNX IN ADVANCE
-- modified at 10:26 Monday 29th May, 2006
|
|
|
|
|
hello
I've found my silly mistake
please help me find error in my code :
class Base
{
public :
virtual ~Base() {};
virtual void getX() const
{
cout<<endl<<"Inside Base : "<<m_X<<endl;
};
protected :
int m_X;
};
class Derived1 : public Base
{
public :
Derived1()
:Base()
{
m_X = 100;
};
virtual void getX() const
{
cout<<endl<<"Inside Derived1 : "<<m_X<<endl;
};
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
throw Derived1();
}
catch (Base *pError)
{
pError->getX();
}
return 0;
}
sorry for stupid question
I am pretty tired, need a good sleep
-- modified at 9:42 Monday 29th May, 2006
|
|
|
|
|
big_denny_200 wrote: virtual void getX() const {
cout<<endl<<"inside base="" :="" "<<m_x<<endl;
}<b="">;
don't close your functions definitions with semicolons (';').
at last, just curious... don't you understand what the compiler says when complaining ?!
i have no compiler to test here, so, sorry.
TOXCCT >>> GEII power
[VisualCalc 3.0 updated ][Flags Beginner's Guide new! ]
-- modified at 9:45 Monday 29th May, 2006
|
|
|
|
|
no
why not use semicolons ?
thanks
-- modified at 9:34 Monday 29th May, 2006
|
|
|
|
|
big_denny_200 wrote: why not use semicolons ?
and you didn't answer my questions more.
* What are the compiler errors ?
TOXCCT >>> GEII power
[VisualCalc 3.0 updated ][Flags Beginner's Guide new! ]
-- modified at 9:45 Monday 29th May, 2006
|
|
|
|
|
toxcct wrote: because the C++ doesn't want them here
In fact, this won't change anything. You can let them there. They will simply be ignored.
Cédric Moonen
Software developer
Charting control
|
|
|
|
|
Cedric have u seen my post? I think that is the reason for his assertion?
SaRath
"D on't blindly follow rules you read somewhere without verifying that it makes sense for your situation!"
|
|
|
|
|
a function ending with ";" is simply compiling with visual studio .net and visual studio 6 C++ compiler.
SaRath
"D on't blindly follow rules you read somewhere without verifying that it makes sense for your situation!"
|
|
|
|
|
it is not the problem with a ";"
problem is with ur try catch block;
big_denny_200 wrote: catch (Base *pError)
u r catching a pointer to the throwing object but inside the
try block u r doing
big_denny_200 wrote: throw Derived1(); // when I add this line I get assert
so inside the throw block do as follows
Derived1 d; // when I add this line I get assert
throw &d;
or
throw &Derived1(); // when I add this line I get assert
u can also resolve if u change the catch block to pass by value instead pass by reference
SaRath
"D on't blindly follow rules you read somewhere without verifying that it makes sense for your situation!"
|
|
|
|
|
SaRath C wrote: Derived1 d; // when I add this line I get assert
throw &d;
Never do this as it’s seriously flawed. The object d is on the stack but the stack is unwound when an exception is caught. The upshot is that when you catch an exception with such code the exception handler gets a pointer to an object which no longer exists. It's the same situation as returning a reference or pointer to a local variable from a function.
Steve
|
|
|
|
|
You're throwing a Derived1 but catching a Base* . If you want to catch a Base* you need code like this:
try
{
throw new Derived1();
}
catch (Base *pError)
{
pError->getX();
delete pError;
}
A better was is not to throw a pointer. Use code like this:
try
{
throw Derived1();
}
catch (const Base &e)
{
e.getX();
}
Steve
|
|
|
|
|
Probably you have seen "winrar" to add "Add to archive" type menuitem to default right-click pop-up menu. I want to add this feature to my file conversion software. After some searching on the internet, I think I have to modify the Windows Explorer context menu. I don't know how to do it. Does anyone know how to do it?
Tamal Saha,
Student,
Bangladesh University of Engineering and Technology.
|
|
|
|
|
|
toxcct wrote: Complete Idiot Guide
Owner drawn
Jesus Loves
|
|
|
|
|
|
toxcct wrote: i didn't name it myself
Thinking about the guys who read it.
toxcct wrote: ps: nice to see you back dear... where were you for all these days ?
Thanks. My ghost was always present here.
Owner drawn
Jesus Loves
|
|
|
|
|
|
Is it really interesting to code with .net framework + C++.
I could not enter into the new world something resisting me to do that
what is ur opinion about new C++ versions and coding with .net?
SaRath
|
|
|
|
|
you'd better ask this in the C++/CLI forum or even in the lounge...
personnaly, i'm not interrested at all in coding for the .NET framework for the moment, in whatever language i could use...
TOXCCT >>> GEII power
[VisualCalc 3.0 updated ][Flags Beginner's Guide new! ]
|
|
|
|
|
toxcct wrote: personnaly, i'm not interrested at all in coding for the .NET framework for the moment, in whatever language i could use...
Thanks for ur reply
SaRath
"D on't blindly follow rules you read somewhere without verifying that it makes sense for your situation!"
|
|
|
|