|
-
Jan 15th, 2002, 10:56 PM
#1
Thread Starter
Frenzied Member
MFC Visual C++ (Beginner)
I have this bit of coding out of Ivor Horton's "Introduction to Microsoft Visual C++ 6.0". Book is great and everything but this is the extent of an actual Windows app. Anyone mind throwing out a little coding for a button that would do something simple like a MessageBox or changing the main window's title?
PHP Code:
#include <afxwin.h> // For the class library
// Window Class definition
class COurWnd : public CFrameWnd
{
};
// Application class definition
class COurApp : public CWinApp
{
public:
virtual BOOL InitInstance();
private:
COurWnd* GetMainWindow() { return static_cast<COurWnd*>(m_pMainWnd); }
};
// Function to create an instance of the main window
BOOL COurApp::InitInstance(void)
{
// Construct an object of our C++ window class
m_pMainWnd = new COurWnd;
// Call Create() to create the underlying window
GetMainWindow()->Create(NULL, _T("Our Simple Window"));
// Call ShowWindow() to display the window
GetMainWindow()->ShowWindow(m_nCmdShow);
return TRUE;
}
// Application object definition oat global scope
COurApp AnApplication;
If anyone wouldn't mind giving an explanation of what's going on with things like "virtual BOOL InitInstance();" (what the hell is virtual?!) or the line "class COurApp : public CWinApp (what's with the public CWinApp after the colon?) it'd really be appreciated.
-
Jan 15th, 2002, 11:20 PM
#2
I'd suggest learning more about C++ before trying to understand this stuff. The public CWinApp and the virtual keyword have to do with inheritance... if that should narrow it down quite a bit.
the public CWinApp means that COurApp is being inherited from CWinApp... I honestly don't know the exact reason for the access specifier... maybe someone else can answer that?
I can't think of a way to explain virtual functions easily... hmm
-
Jan 16th, 2002, 07:52 AM
#3
virtual is very easy.
If you define a class as virtual, like this:
Code:
virtual void myMethod();
...In a class, and then derive a second class from this one:
Code:
class aClass : public someOtherClass
and do NOT define the method "myMethod" inside of the second class, when you use that method from an instance of aClass, it will use the implementation defined in someOtherClass. If you DO define this method in aClass, it will use the method implementation in aClass. Consider:
Code:
class base { base(){}
virtual void method() { cout << 10 << endl; }
};
class derives : public base { derives() {}
void method() { cout << 5 << endl; }
};
int main() {
derives d;
d.method();
base b;
b.method();
return 0;
}
This sample program will output:
That should be enough to get started.
Z.
-
Jan 16th, 2002, 04:15 PM
#4
Zaei: your app will output
10
5
even if the funtion is not virtual. I could write a 2 page essay about virtual, but I won't do it. Shawn: you should really learn the basics of C++ first. See the tutorials at the top of this page.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jan 16th, 2002, 05:08 PM
#5
I have a question?
Code:
class Derived : public Base
The access specifier... when would you use something other than public? I have only ever seen public being used.
-
Jan 16th, 2002, 05:32 PM
#6
Thread Starter
Frenzied Member
No button coding?
-
Jan 16th, 2002, 06:14 PM
#7
transcendental analytic
Originally posted by amac
I have a question?
Code:
class Derived : public Base
The access specifier... when would you use something other than public? I have only ever seen public being used.
private inheritance is rather like delegation, the only good use i've had of them was concentrating data using templates something like
template <class A,class B>class C rivate A,private B{
template <class X>something(X a){return A.something(a)&&B.something(a)};
template <>something<int>(int a){/**/};
where the call would be nested in private...
Well things have changed now and I don't have that class anymore so I don't remember how it was for sure, but it was usefull at that point of time.
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Jan 17th, 2002, 02:57 AM
#8
Hyperactive Member
-
Jan 17th, 2002, 07:52 AM
#9
I dont think so CornedBee. I just tested the code (without the virtual functions, thanks for that, need to do a bit more reading). Here is the path:
Code:
int main() {
derives d;
d.method();
base b;
b.method();
return 0;
}
derives::derives()
derives::method() (cout << 5 << endl;)
base::base()
base::method() (cout << 10 << endl;)
return 0;
Correct?
Z.
-
Jan 17th, 2002, 09:07 AM
#10
virtual inheritance does only make sense when you're going to have a pointer or reference to the base class but it is really pointing to the derived class. See here:
PHP Code:
class Base
{
void WhoAmI() { cout << "Base" << endl; };
virtual void WhoAmIReally() { cout << "Base" << endl; };
};
class Derived : public Base
{
void WhoAmI() { cout << "Derived" << endl; };
virtual void WhoAmIReally() { cout << "Derived" << endl; };
};
int main()
{
Base b;
b.WhoAmI(); // outputs "Base", that's simple
Derived d;
d.WhoAmI(); // outputs "Derived" because d is of type Derived
// although not virtual, the compiler knows it's Derived
// WhoAmIReally gives the same results
Base *pb = &b;
pb->WhoAmI(); // still not surprising: "Base"
Derived *pd = &d;
pd->WhoAmI(); // also not surprising: "Derived" because pointer points to Derived
// but now it get's interesting:
pb = &d; // absolutely legal: downcast
pb->WhoAmI(); // "Base", because compiler thinks it's of type Base like the pointer
// virtual function calls are not resolved at compile time
// but rather at runtime, this works like it should
pb->WhoAmIReally(); // "Derived", because object that is pointed to is of class Derived
return 0;
}
For references (Base& rb) it's the same.
I could now explain why it works. As I said, 2 page essay. But I'll rather answer the other question:
The access specifier when deriving tells how the members of the parent class(es) are to be treated.
class Derived : public Base
This is the most common way. Members of Base keep their access specifiers.
class Derived : protected Base
Members of the base class can't be accessed from outside the class. They can, however, be accessed from inside the class or from derived classes as long as they weren't declared as private in the first place.
class Derived : private Base
Members of Base can't be accessed from outside or from derived classes, only from within Derived. Derived has to provide it's own public/protected methods to give access to the members.
Ok, this was a little overview of the possibilities. I can think of only one use now: Imagine you have a class that manages a dynamic array. Now you want to derive a class that does the same but only allows two types of access: add something to the front or get something from the back (queue). To avoid having to create the whole memory management mechanism again you want to derive this class from your dynamic array, but you want to hide all functions except AddFront and GetBack (or whatever). Solution: derive as private and give the derived class the methods AddFront and GetBack that internally call the base class' methods.
This is actually what the STL containers stack and queue do, except they use a private member of the dynamic array container (deque, vector or list) instead of deriving from it.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jan 17th, 2002, 01:28 PM
#11
transcendental analytic
CornedBee:
Private breaks the "is a" relationsship, will protected do the same? If the public and protected members in the base become protected in the derived those won't be accessible and therefore breaking compability with the base, am I right?
If so, delegation should be a better alternative to private inheritance. Regarding protected inheritance you could benefit from access to protected members in the base class, which delegation doesn't provide, but private inheritance seems superfluous
Also another thing, I know polymorphism breaks inlining but, declaring a function virtual inline for inlining when the base class pointer is not supplied but the derived class itself is called on, will it inline?
btw, I guess you meant "virtual functions" instead of "virtual inheritance", since it refers to elimination of duplicate baseclasses when using multiple inheritance (that would cause ambiguety problems when accessing its members as well as take up twice as much space in the derived class)
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Jan 17th, 2002, 05:46 PM
#12
That makes perfect sense, CornedBee. Thanks. Basically, any time you need to refer to an object using a pointer that is of a type the the object derives from, you need to use virtual functions, right-o?
Z.
-
Jan 17th, 2002, 08:54 PM
#13
transcendental analytic
Note that virtual calls won't inline and that the overhead of 4 bytes per base class with virtual functions on each instantiated derived object and the overhead of retrieving the type information and the call from v-table for each virtual call on the derived class referenced by base pointer. So in other words polymorphism can be pretty expensive and should be avoided when unnessesary and when the overheads can be critical.
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Jan 21st, 2002, 06:05 PM
#14
Keda 1:
I said it's the only thing I can think of, I didn't say it's the best way. I don't see any real use for private inheritance (but your idea for protected inheritance does make some sense, although I think it breaks the OOP blackbox philosophy: a class should not derive from another just to have access to protected members).
Whether a function inlines depends very heavily on the compiler, I think VC++ is very good at that (better than at templates ), but if you call the function directly on an object (neither reference nor pointer) I think it should inline.
Yes, I meant virtual functions. Virtual inheritance is something I know in theory but I doubt i will ever have a need for it. Multiple inheritance is seldom enough.
Zaei:
Not always, but most of the time. You need to use virtual functions when you want the version of the derived class to be called. If you're content with the version of the base class (usually only when there is no version of the derived class) you don't need virtual (but then it is not inherited anyway). So, in practical terms, the answer is "Yes".
Keda 2:
I think the memory overhead is only 4 bytes no matter how many base classes with virtual functions there are (or is there more than one vtable then?).
Here's some assembly of a COM call (IDirectDrawSurface4->Blt())
It has the following parameters:
RECT* prcDest // destination area
LPDIRECTDRAWSURFACE4 pSrcSurf // source surface
RECT* prcSrc // source area
DWORD flags // flags
DDBLTFX* pbltfx // DDBLTFX structure, contains other blitting information
I want to fill the surface with a color, so supply NULL for first three args.
Set flags to COLORFILL and WAIT (0x01000400)
Code:
push edx ; edx = &ddbltfx
push 01000400H ; flags
push 0
push 0
push 0
mov eax, DWORD PTR _lpdds$[esp+100] ; get surface pointer from args, this is VC++ optimized code, so no ebp
push eax ; this pointer
mov ecx, DWORD PTR [eax] ; eax is pointer to surface, we want vtable which is always first member of class
call DWORD PTR [ecx+20] ; 20 is offset of Blt in vtable
The same thing for a normal class, parameter pushing not included a second time
Code:
mov eax, DWORD PTR _lpdds$[esp+100] ; get surface pointer from args, this is VC++ optimized code, so no ebp
push eax ; this pointer
call ?YVIDirectDraw4@BltWYSIWYG@DDBLTFX_@RTFM ; or whatever weird name
Overhead = 2 * memory dereferencing + 1 * mov = about 5 cycles at max, but I don't know if the memory offset (ecx+20) needs cycles
It's not much but can be relevant in time critical things. But if it's fast enough for DirectX...
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jan 21st, 2002, 07:01 PM
#15
transcendental analytic
Code:
class a{virtual ~a();};
class b{virtual ~b();};
class c:public a,b{};
void main(){
cout <<sizeof(c);
};
This displays 8 in MSVC6, although I'd think there would be needed two different v-tables per base class (if they inherit from different functions, the indexing would screw up) I wonder why they can't harcode the fact that each base pointer would only be able to call their own derivates functins (if you put the v-tables in the base classes)
Overhead = 2 * memory dereferencing + 1 * mov = about 5 cycles at max, but I don't know if the memory offset (ecx+20) needs cycles
It's not much but can be relevant in time critical things. But if it's fast enough for DirectX...
5 cycles + breaks inlining, and guess how many times you could do otherways when creating an application with DirectX seldom you really have practical use of the polymorphism I'd say. Compare STL and DirectX, STL flexible and generic, inlines to efficient fast code, DirectX object oriented and dynamic, slow and ugly.
although I think it breaks the OOP blackbox philosophy: a class should not derive from another just to have access to protected members).
You are absolutlely right, protected is meant to be member sharing for is a-related classes, and protected inheritance does not maintain is-a relationship, still it can sneak into it's "base" protected members. I think you could do similar by deriving it public and share the protected data, but this exposure shows at least a connection between the classes. I guess declaring a member protected means that it's almost public, just not directly.
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Jan 22nd, 2002, 07:52 AM
#16
Code:
PUBLIC ??_7c@@6Ba@@@ ; c::`vftable'
PUBLIC ??_7c@@6Bb@@@ ; c::`vftable'
This is from a class derived from 2 base classes. Seems you're right keda. Therefore, the simplest COM object has 8 bytes extra need. (IUnknown vtable and IMyCOM vtable).
For DirectX, the good thing is that most functions are so long that inlining doesn't matter and the 5 cycles are nothing compared to the need of the function.
COM wasn't designed for speed. It was designed for cross-language and backwards compatibility. Both is achieved very well with the polymorphism. Templates on the other hand couldn't be used anywhere but with C++. DirectX may be ugly, but it certainly is not slow. At least not so slow that it matters, otherwise OpenGL would be the only thing used. I also don't compare STL and DirectX because they were designed for completely different purposes: STL: helper templates for C++ - DirectX: multimedia library for all languages.
I wonder why they can't harcode the fact that each base pointer would only be able to call their own derivates functins (if you put the v-tables in the base classes)
I don't really understand. What do you wanna do?
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Jan 22nd, 2002, 10:13 PM
#17
transcendental analytic
For DirectX, the good thing is that most functions are so long that inlining doesn't matter and the 5 cycles are nothing compared to the need of the function.
DirectX is built in such a way that expensive operations are nicely encapsulated, and ready for common usage, I'd have to agree that it's not to worry about, DirectX was a bad example of how you can screw it up with OOP. Programming redirection of hardware layers is constrast to Generic Programming; from many layers into one. Having all the micromanagement out of the way the user won't need to mess with critical algoritms. But when you use API, you are stuck with that, so portability is upto the API, the more of it, the more abstraction needed, and the less efficient it will become.
I also don't compare STL and DirectX because they were designed for completely different purposes: STL: helper templates for C++ - DirectX: multimedia library for all languages.
Though I'm comparing paradigms here, I was aiming at the unpromising use of Object Orientation ands it's demands on diversification, polymorphism and abstraction versus efficciency. In contrast API designed for generic use would inline when possible and bypass memory and dereferencing hogs. STL provides generic layers from a single concept; algoritms and containers. So from one to many. The generic algoritm doesn't need any depencies, they are added as needed, static or dynamic, whichever you like.
don't really understand. What do you wanna do?
Never mind, I wasn't thinking straight, multiple layers per class that won't interfer with others would work, but we know the wonders with multiple inheritance, one for all and all for one (base for derived class)
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Jan 22nd, 2002, 10:19 PM
#18
Thread Starter
Frenzied Member
WHAT ABOUT WHAT I WANT TO DO~@$!!!
-
Jan 22nd, 2002, 10:27 PM
#19
transcendental analytic
you want to learn MFC or Object Orientation? There are good tutorials in both, but I have not MFC reference at the moment, only familiar with win32api, MessageBox for messageboxes and SetWindowText for changing window caption, you can check up the syntax in MSDN
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Jan 23rd, 2002, 10:14 AM
#20
Code for a button (but I don't think this is a good way for learning...)
PHP Code:
// Add this to your view class:
// Section "Attributes":
CButton m_but;
// Section "Generated Message Map Functions":
afx_msg void OnButtonClick();
// Add this in the implement file:
// Using class wizard, override the virtual function OnInitialUpdate and write this:
m_but.Create(_T("Hit me!"),
BS_PUSHBUTTON | WS_VISIBLE,
CRect(100, 100, 180, 130),
this, 1);
// just below, add this:
void (YourViewClassName)::OnButtonClick()
{
MessageBox(_T("You did it!"));
}
// And add this to the message map, between the
// BEGIN_MESSAGE_MAP and END_MESSAGE_MAP macros:
ON_COMMAND(1, OnButtonClick)
 
I can explain it too, but not now.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|