|
I did only changed the following, i just migrate the implementation from the .h to .cpp and it worked.
Look this is what i had originaly at first in a .h, which is the way it did not worked
//base.h file
struct A;
struct B;
struct A
{
int lolipops;
B* candy;
A(B* ptr)
{
lolipops = 0;
candy = ptr;
}
action(int pass)
{
candy->gums = pass;
}
};
struct B
{
int gums;
A* candy;
B(A* ptr)
{
gums = 0;
candy = ptr;
}
action(int pass)
{
candy->lolipops = pass;
}
};
The way it worked is the following i only declared the structs in .h and implemented it on the .cpp file like this:
.h file
struct A;
struct B;
struct A
{
int lolipops;
B* candy;
A(B* ptr);
void action(int pass);
};
struct B
{
int gums;
A* candy;
B(A* ptr);
void action(int pass);
};
in .cpp file
#include "base.h"
A::A(B* ptr)
{
}
void A::action(int pass)
{
candy->gums = pass;
}
B::B(A* ptr)
{
candy = ptr;
}
void B::action(int pass)
{
candy->lolipops = pass;
}
and that is what changed, so trying to do everything in the .h file does not work
|
|
|
|
|
You can make it work even if you put it all in the .h file
struct A;
struct B;
struct A
{
int lolipops;
B* candy;
A(B* ptr) {}
inline void action(int pass);
};
struct B
{
int gums;
A* candy;
B(A* ptr) {}
inline void action(int pass);
};
inline void A::action(int pass)
{
candy->gums = pass;
}
inline void B::action(int pass)
{
candy->lolipops = pass;
}
|
|
|
|
|
this way works perfectly so i have to implement the non-constructor code outside the struct body and it worked, Thanks
|
|
|
|
|
Basically it all comes down to the compiler being incapable of reading ahead: the moment you do something you have to make sure that all neccessary defintions have been made before:
struct A;
struct B;
struct A {
int gummy;
B* myb;
A() : myb(0) {}
void set(B* b) {
myb = b;
gummy = b->bears;
}
};
struct B {
int bears;
A* mya;
B() : mya(0) {}
void set(A* a) {
mya = a;
bears = a->gummy;
}
};
You can skip the forward declaration of A here, but you have to move the implemetation of A::set() to a later point in your code, so the compiler gets a chance to read the declaration of B first:
struct B;
struct A {
int gummy;
B* myb;
A() : myb(0) {}
void set(B* b);
};
struct B {
int bears;
A* mya;
B() : mya(0) {}
void set(A* a) {
mya = a;
bears = a->gummy;
}
};
void A::set( B* b )
{
myb = b;
gummy = b->bears;
}
Does this help?
|
|
|
|
|
Yes it helps, i now understand more of the problem here so this is compiler dependent then. Thanks for your time i have learned from all you!!
|
|
|
|
|
Yes, I know it's legal, but that is not what the OP had in his/her definitions.
I must get a clever new signature for 2011.
|
|
|
|
|
I know you know. There was just great confusion.
|
|
|
|
|
code like this:
class Your
{
public:
My my[3];
};
class My has no default constructor, as:
class My
{
public:
My(int iv)
{
}
};
how do you init class array my[3]?
is it impossible?
|
|
|
|
|
I'm not near a compiler, but it *might* work...
If Your::My was not an array, then you could do this:
Your::Your ()
: My (42)
{
}
I'm wondering if:
Your::Your ()
: My [0](42), My [1](420), My [2](3)
{
}
would work.
Iain.
I am one of "those foreigners coming over here and stealing our jobs". Yay me!
|
|
|
|
|
A class is responsible for its data members. An external user thus shouldn't care what the class does with the data members. And the class itself should add a default ctor if there is a need.
And the initial value will be zero so is that not sufficient?
If you are trying to circumvent the class itself without altering the code, then you can manipulate it via a pointer. That of course requires a bit of spelunking as to the exact data in the class, but with your example it should be just a zero offset.
|
|
|
|
|
The particular condition "array of objects without default constructor" makes, as far as I know, your code not viable. The easiest workaround is, in my opinion, adding the default contructor to your My class.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
The only way to initialize standard arrays is aggregate initialization:
My my[] = {3,5,11};
My my3[3] = {3,5,11};
My my4[4] = {3,5,11};
The easiest way to solve your problem thus would be to add a default constructor to class My.
If that isn't an option, you can work around this issue by separating the allocation of the required memory and its initialization like this:
class My {
int val;
public:
My(int i) : val(i) {}
int get() const {return val;}
};
class Your {
char myPlaceHolder[3][sizeof(My)];
My* my;
public:
Your()
{
my = (My*)(myPlaceHolder);
new (&my[0]) My(3);
new (&my[1]) My(5);
new (&my[2]) My(11);
}
int operator[](int i) const { return my[i].get(); }
};
void testYour() {
Your your;
std::cout << "my[0]="<<your[0] << " ; my[1]="<<your[1] << " ; my[2]=" <<your[2] << std::endl;
}
The function testYour() will print "my[0]=3 ; my[1]=5 ; my[2]=11"
|
|
|
|
|
Hi everyone
I'm interested in coding programs that work with the web.
Most of the times, I need to host some web-browser in my application and use CHtmlView for it.
I would like to try to host Firefox in my applications too. Since it is opensource, is not it possible to use it in the mfc application?
Thank you in advance.
|
|
|
|
|
May be it doesn't suppsoed.
|
|
|
|
|
There is an article at https://developer.mozilla.org/en/Gecko_Embedding_Basics[^] which covers the basics on embedding the gecko engine into a program.
The fact that you are using MFC is meaningless, you may need to make a wrapper class, but it will work.
You may also want to look at the SpiderMonkey[^] article too, as that may help if you are wanting to use JavaScript.
|
|
|
|
|
You could possibly take the source code of Firefox and extract the parts that make up the actual browser control and include that in your application, but I do not think it would be an easy task.
I must get a clever new signature for 2011.
|
|
|
|
|
msn92 wrote: Since it (firefox) is opensource, is not it possible to use it in the mfc application?
is your program open source ?
Watched code never compiles.
|
|
|
|
|
LPBYTE bReadFile(DWORD sizeToRead)
{
LPBYTE _b = new BYTE[sizeToRead];
ReadFile(_handle,_b,sizeToRead,&dwReadSize,NULL);
return _b;
}
int main()
LPBYTE reader;
reader = bReadFile(512);
how to free the variable LPBYTE reader;
as it is not initialized using new/malloc, so i cannot use delete[]/free.
LPBYTE reader
Need Help
Some Day I Will Prove MySelf :: GOLD
|
|
|
|
|
simply delete it
delete reader
goldenrose9 wrote: as it is not initialized using new/malloc, so i cannot use delete[]/free.
You are returning the new 'ed _b , which in turn gives you back the ref of _b . So, even though you did not do new on reader , it still points to the same mem as _b and is ok to call delete on it.
|
|
|
|
|
Yusuf wrote: delete reader
when i call delete reader then
Debug Assertion Failed error occurs.
Some Day I Will Prove MySelf :: GOLD
|
|
|
|
|
Which form of delete are you calling? As you've allocated the block of memory using the array form of new you have to delete it the same way (e.g. use delete [] reader; NOT delete reader; ).
Cheers,
Ash
|
|
|
|
|
i had tried both
delete reader and
delete []reader
Some Day I Will Prove MySelf :: GOLD
|
|
|
|
|
In that case it sounds like you're mangling the heap somehow - some other pointer related operation is destroying a heap data structure so it can't work out what to do with the pointer you're giving it. The best thing to do in this case (which isn't practical in every case) is to go on a pointer purge and convert them to slightly less dangerous objects. In the short term check that the memory around your buffer isn't scribbled on by something else during it's lifetime.
Cheers,
Ash
|
|
|
|
|
It looks like you're getting confused by what a pointer is. A pointer is just a variable that can be set to the addresses of arbitrary chunks of system memory. You don't need to "free" reader but you have to release whatever it points to back to the compiler's runtime. In the case you've presented all you have to do is:
delete [] reader;
when you've finished with the block of memory the pointer points to.
However the way you've written the code is a bit crap - if anything throws an exception between calling bReadFile and the delete you're going to leak memory. Instead of using an array consider using something with a bit more behavioural intelligence - e.g. std::vector. Then you'll not have to worry about cleaning up after yourself:
std::vector<char> read_from_file( std::size_t bytes_to_read )
{
std::vector<char> bytes_read( bytes_to_read );
std::size_t number_bytes_read = 0;
ReadFile( handle_of_file, &bytes_read[ 0 ], &number_of_bytes_read, 0 );
return bytes_read;
}
The code there will be within 5% of the performance of what you've written (faster on some compilers as there's no pointer aliasing) AND exception safe.
Cheers,
Ash
PS: Anyone who thinks there's an expensive copy of the vector returned to the caller should upgrade their compiler.
|
|
|
|
|
Since you're bringing performance up, the output parameter alternative might be a lot faster under some conditions. Especially when you're calling read_from_file() several times in a loop, which is most likely.
std::vector<char>& read_from_file( std::size_t bytes_to_read, std::vector<char> &bytes_read )
{
bytes_read.reserve( bytes_to_read );
std::size_t number_bytes_read = 0;
ReadFile( handle_of_file, &bytes_read[ 0 ], &number_of_bytes_read, 0 );
bytes_read.resize(number_of_bytes_read);
return bytes_read;
}
Edit: Forgot to resize the vector.
home
modified on Saturday, February 12, 2011 12:57 PM
|
|
|
|