Auto cast an iterator into its base pointer type ?

The Partridge Family were neither partridges nor a family. Discuss.
User avatar
chili
Site Admin
Posts: 3948
Joined: December 31st, 2011, 4:53 pm
Location: Japan
Contact:

Re: Auto cast an iterator into its base pointer type ?

Post by chili » March 19th, 2020, 4:13 pm

Didn't you try and *form* a C habit for a while? :D
Chili

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Auto cast an iterator into its base pointer type ?

Post by albinopapa » March 20th, 2020, 8:32 am

Ha, no sir. I wanted to "C" what it was like. I had an argument with a C programmer on a YT channel and they made the comment that C++ programmers don't know what they are talking about when it comes to C thinking that just because C++ came from C that they are still the same language. While I did find some things different like variable length arrays ( stack allocated arrays that can be allocated dynamically instead of at compile time ) kind of cool, I mostly did it for the academic purpose. I suppose it was a little enlightening.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

binbinhfr
Posts: 78
Joined: May 9th, 2019, 10:57 pm

Re: Auto cast an iterator into its base pointer type ?

Post by binbinhfr » March 22nd, 2020, 1:24 pm

albinopapa wrote:
March 19th, 2020, 7:08 am
I've tried helping someone break the C habit, it wasn't easy for them.
Yes. For example I use classes and methods, but at the end, I put everything in public because I want to easily access every member from anywhere... I know it's bad. :-(

User avatar
chili
Site Admin
Posts: 3948
Joined: December 31st, 2011, 4:53 pm
Location: Japan
Contact:

Re: Auto cast an iterator into its base pointer type ?

Post by chili » March 22nd, 2020, 2:38 pm

I feel like education in universities etc. have really failed in teaching OOP. They show you what a class is, what inheritance is, etc. etc., but there is far too little time spent on the why. So many people just end up creating classes because "that's what you do", without ever really knowing why this became a thing in the first place.
Chili

binbinhfr
Posts: 78
Joined: May 9th, 2019, 10:57 pm

Re: Auto cast an iterator into its base pointer type ?

Post by binbinhfr » March 22nd, 2020, 2:56 pm

You're right. Coming from C, I use classes mostly as super-structs. I watched all your videos, and understand almost everything technically, but when it's time to design a real complex project, I have no problems to choose Classes and what they should be used for, but when coming to methods, I often don't know how to design them nicely, in order to take advantage of what I learn in your videos, all this protection that C++ offers and that leads many C programs to bugs.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Auto cast an iterator into its base pointer type ?

Post by albinopapa » March 22nd, 2020, 4:50 pm

binbinhfr wrote:
March 22nd, 2020, 1:24 pm
albinopapa wrote:
March 19th, 2020, 7:08 am
I've tried helping someone break the C habit, it wasn't easy for them.
Yes. For example I use classes and methods, but at the end, I put everything in public because I want to easily access every member from anywhere... I know it's bad. :-(
One of the things that this person couldn't wrap their head around was that C++ automatically passes an instance of the class object to it's own methods. So when he created methods he would always put a reference to that classes object.

Code: Select all

class Thing
{
public:
     void Do( Thing& thing );  // <- This is what they would do
     void Do();  // Instead of doing this
};
He too would complain about private members/methods calling it "Hand holding" and he didn't feel it was necessary. Unfortunately, he got pretty frustrated with me and we parted ways.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

binbinhfr
Posts: 78
Joined: May 9th, 2019, 10:57 pm

Re: Auto cast an iterator into its base pointer type ?

Post by binbinhfr » March 22nd, 2020, 5:11 pm

Well I'm happy to tell you that I'm a little more advanced ;-)
My main problem is about public members. As I told you, most of the time, I want to access almost any member from any other class... For example, I hate these "Set..." and "Get..." methods to access members...
I start to put some inheritance in my classes, so I guess I am on the good road ;-)
I posted a topic on multithread, do you have any knowledge on this subject ? Because I'm stucked.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Auto cast an iterator into its base pointer type ?

Post by albinopapa » March 23rd, 2020, 12:32 am

I've taken a look at it and while I'm not very experienced in MT, I will see what I come up with.

As for the get/set methods, they can be beneficial. Say you want to keep a value between a certain range. If the member is public, you'll always have to write clamping code everywhere you set the value. If you use a set function, then that function can just clamp the value. As for the getter function, they may not make as much sense. One thing that I've started trying to do is avoid get/set functions and just decide what I want to do with the members I'm wanting to get/set, then just make a method that does that in the class so I don't have to use the getter/setter functions. This way you maintain encapsulation and not have to write as many get/set functions. Another thing you might consider is writing friend functions that manipulate data if more than one class needs to be manipulated at the same time.

Using chili's poo game as an example, the poo and the dude need to interact when testing for collision so free functions that are friends to both allows you to maintain encapsulation with the rest of the code and separation between Poo and Dude classes.

Code: Select all

class Dude
{
     friend bool IsDudeCollidingWithPoo( Dude const&, Poo const& );
};

class Poo
{
     friend bool IsDudeCollidingWithPoo( Dude const&, Poo const& );
};
bool IsDudeCollidingWithPoo( Dude const& dude, Poo const& poo )
{
     return
          ( ( dude.x >= poo.x + poo.width ) && ( dude.x + dude.width < poo.x ) ) &&
          ( ( dude.y >= poo.y + poo.height ) && ( dude.y + dude.height < poo.y ) );
}

// Usage:
if( IsDudeCollidingWithPoo( dude, poo ) )
{
     // Handle collision
}
In this example, no get/set functions were written and Dude and Poo don't need to interact directly. If there is no pattern for accessing the members, then maybe setting them public isn't a bad idea, however if maintaining some limit or "invariance" then create member functions that deal directly with the data or make the get/set functions to maintain that invariance. This keeps the main logic part of the program clean and avoids bugs that would be caused by not maintaining the invariance.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

binbinhfr
Posts: 78
Joined: May 9th, 2019, 10:57 pm

Re: Auto cast an iterator into its base pointer type ?

Post by binbinhfr » March 23rd, 2020, 1:41 pm

Yes, I totally agree with all you said. I see all the benefits of an intelligent C++ approach. But the fact is that most of the time I'm lazy to program this way. Which , I admit, is a poor calculation, because investing some time in class/methods design can avoid a lot of problems that C programmers were always bumping into.

Another stupid reason is that, as an old programmer, I always think about "speed optimisation", because in the 80-90's, you needed to think about it in every piece of you code. Now, it's almost useless, when you see the power of CPU. But it stays in my genes... And all these C++ checking take some CPU times. And I see that in game programming, it can be an issue. (think of some games like rimworld or factorio or oxygen not included, that can slow down when you grow your map).

I remember a MIDI sequencer I wrote under DOS, before windows, in console mode. There was no multithreading libs at this time. But I implemented my own 2-threads program in Turbo C 2.0 :
There was 1 relax thread for the program interface/display, and 1 priority thread for the MIDI input/ouput flow to the MIDI card. I wrote a little 80x86 assembler routine (directly embeded in the C code) to switch from one thread to another, swaping stacks and registers at every tick of a timed event (there was no more event handler at this time). Incredible to be able to do this, no ? I spent a lot of time to debug it, believe me. I found old doc on the subject :
https://www.ic.unicamp.br/~celio/mc404/ ... d-asm.html

I'm sure that chili would have loved it !!!! ASM mixed with C !!! :-D

But it was the only solution to make the program work in a smooth way.

Would love to see your ideas on MT, in the other forum subject.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Auto cast an iterator into its base pointer type ?

Post by albinopapa » March 23rd, 2020, 4:56 pm

And all these C++ checking take some CPU times.
Not sure exactly what you mean there. What checking is there in C++ that you wouldn't have in a C program?

As an example in your MT project, you have public access to your condition_variable named cv in your Prog class. If you were to make a member function called WakeUp() or something similar, you could hide ( make cv private ) and it shouldn't add any overhead.

Current usage:
prog[ i ].cv.notify_one();

Proposed usage:
prog[ i ].WakeUp();

This can be implemented simply:
Prog::WakeUp(){ cv.notify_one(); }

Name it whatever, like WakeThread() or NotifyThread() or keep the WakeUp(). The point I'm making here is the code is cleaner, more descriptive and safer since you wouldn't be exposing your condition variable in this case, and you get the same functionality without having to write a get function ( I suppose you could consider this a set function ).

Just thought of something:

Code: Select all

template<typename Fn, typename...Args>
void ThreadSafeCall( std::mutex& mtx, Fn funcToCall, Args&&... funcArgs )
{
     auto guard = std::lock_guard( mtx );
     funcToCall( std::forward<Args>( funcArgs )... );
}
What this function would do is lock the mutex, call the funcToCall with the parameters funcArgs.
An example would be a modified version of your Print function.

Code: Select all

void Print( const std::string& s )
{
	// shared display routine
	mutex_display.lock();
	std::cout << s << std::endl;
	mutex_display.unlock();
}

// Changes to just:
void Print( const std::string& s )
{
	std::cout << s << std::endl;
}

// And called like:
ThreadSafeCall( mutex_display, &Print, "CREATING " + std::to_string( tot_threads ) + " THREADS"  );
Of course, this would mean that the entire function has to complete before the mutex is released, so for longer functions you'd either have to break them up into smaller functions or use lambdas to break the function up into sections.

I'm not much of a MT guy, haven't done enough with it, but the C++ language as well as a moderate level of template usage I can do. I want to say that there should be a way to use the notify_all() function of the condition variable instead of having to loop through each thread to wake each one up, but I really don't understand enough of it.

Originally I thought each thread was suppose to share a mutex so each thread knew when things were locked, but it seems I was wrong. I had some pretty bad slow downs doing it this way and I haven't gone back to learn about multithreading for some reason.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

Post Reply