C++ - Method Override Isn't Expressed as Expected - c++

I have a Base class Point (representing a 2D point in space) that is non-thread-safe for move operations; so I defined an inherited class LockedPoint that overrides 2 methods in the base class: moveTo and moveBy:
void Point::moveTo(float xPos, float yPos) {
x = xPos;
y = yPos;
}
void Point::moveBy(float xOff, float yOff) {
x += xOff;
y += yOff;
}
void LockedPoint::moveTo(float xPos, float yPos) {
MutGuard m(lock);
x = xPos;
y = yPos;
}
void LockedPoint::moveBy(float xOff, float yOff) {
MutGuard m(lock);
x += xOff;
y += yOff;
}
( where x and y = private member variables,
lock = a private mutex, and
MutGuard = typedef lock_guard<mutex> )
To visually see the problem with the "unlocked" Point, I wrote up a test routine:
void sleepForMS(long ms) {
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
void messWithPoint(Point& p, int type) {
float n = 1;
if (type) n *= -1;
for (long i = 0; i < 10000; i++) {
p.moveBy(n, n);
sleepForMS(rand() % (type ? 2 : 3));
if (i % 500 == 0)
std::cout << i << ":\t" << p << std::endl;
}
}
int main(int argc, char* argv[]) {
using namespace std;
Point p;
thread t1(messWithPoint, std::ref(p), 0);
sleepForMS(33);
thread t2(messWithPoint, std::ref(p), 1);
cout << "Started\n";
t1.join();
t2.join();
cout << p << endl;
}
With a Point, the resulting p is "corrupted", as expected (it should equal (0,0) by the end, and it doesn't). If I change p to a LockedPoint though, the base version of moveBy is still called (verified by print debugging).
I read up on method "overriding" (apparently more correctly called "method hiding"), and from what I understand, if the overriding method has the same signature as the base method, it hides the base version, and is called instead. Why then is the base method being called despite the 2 having the same signature? The only thing I can think of is because I'm specifying Point in messWithPoint's argument list, it's taking that literally and calling Point's version. If I change the signature to void messWithPoint(LockedPoint& p, int type), the resulting LockedPoint is (0,0), as expected. Shouldn't it "see" that the passed LockedPoint overrides the used method, and use the "least hidden" version?
If that's not how it works, is there a way to specify taking the base class, but having it use any available overridden versions?

The member functions are not virtual, so the functions in the class known at compile time are used.
However, for a simple class such as point, using virtual member functions or providing automatic mutual exclusion goes against the C++ idea of not paying for what you don't use.
Just copy points.

Related

I wrote a class. And when I specified the function, it failed

class equation
{
public :
int k;
int l;
int t;
float x1_value;
float x2_value;
float b1 = sqrt(l^2 -4*k*t);
float equation1;
equation();
~equation();
};
float void equation::equation1() {
if (b1 == 0)
{
float x1_value = -l/2*k;
cout << " joongen. " <<x1_value <<endl;
}
else if (b1 > 0)
{
float x1_value = ((-l + sqrt(b1) / (2*k));
float x2_value = ((-l - sqrt(b1) / (2*k));
cout << "x is 2"<< x1_value < " x 2 is "<< x2_value <<endl;
}
else
{
cout <<"imagine number ."<<endl;
}
return (0);
};
The code produces this error:
error: two or more data types in declaration of 'equation1'
float void equation::equation1() {
^
I can make out two problems.
First you define equation1 as a member variable with type float. You might want to change that into a function declaration.
// ...
float equation1();
// ...
The second problem is pointed out in the comments. If you implement your function, you should only use one return type. As I can only guess, what return type you would really want, I take float, since it is in your faulty function declaration.
// ...
float equation::equation1() {
// ...
}
// ...
One extra thing, that disturbs me every time I see someone who is new with C++. Please, please, please, don't use using namespace std;. I assume you do so, because of the missing std::. You open up an fastly huge namespace. You may end up defining a function, with the same name and parameters and encounter a very cryptic error, which is nearly impossible to figure out.

C++ Function Polymorphism - Unexpected Behaviour

I'm quite new to C++ and come from a Python background. Basically, I want a collection of "State" objects, each of which should have its own "Distribution" object. Different states can have different types of distribution (uniform, normal, etc.). I want to be able to evaluate the probability of some observation passed to a state without worrying about what that state's distribution is. It occurs to me that's what polymorphism is for. However, if I calculate the PDF for an observation, then change one of the distribution parameters (say, the mean) then I still get the same answer from the PDF function call. Clearly there is some issue of scope, updating, etc. that I'm not understanding; I would be very grateful for an explanation. I've produced a shortened snippet of code which I hope describes my question. While I had a look for similar issues, I couldn't find anything that quite answered my question - nevertheless, sincere apologies if this is a repeat post.
#include <iostream>
#include <math.h>
class Distribution{
/*polymorphic class for probability distributions */
protected:
Distribution( double, double );
public:
double param1, param2;
virtual double pdf( double ) = 0;
};
class NormalDistribution: public Distribution {
/*derived class for a normal distribution */
public:
NormalDistribution( double, double );
double param1, param2;
double pdf( double x ){
return ( 1.0/sqrt( 2.0*pow( param2, 2.0 )*M_PI ) )*exp( -pow( x - param1 , 2.0 )/( 2.0*pow( param2, 2.0 ) ) );
}
};
Distribution::Distribution( double x, double y ){
param1 = x;
param2 = y;
}
NormalDistribution::NormalDistribution( double x, double y ): Distribution( x, y ) {
param1 = x;
param2 = y;
}
class State {
/*simple class for a state object that houses a state's distribution */
public:
Distribution *dist;
State( Distribution * x){
dist = x;
};
};
class myBoringClass{
public:
int x;
int myBoringFunction(int y){
return x*y;
}
};
int main(){
//For polymorphic NormalDistribution class
NormalDistribution nd2(0.0,1.0);
NormalDistribution *np = &nd2;
State myState(np);
//Set an initial mean, std and evaluate the probability density function (PDF) at x=0.5
std::cout << "PDF evaluated at x=0.5, which should be 0.352: " << myState.dist -> pdf(0.5) << std::endl; //this gives the right answer, which is 0.352
//Now change the mean and evaluate the PDF again
myState.dist -> param1 = 2.0;
std::cout << "PDF evaluated at x=0.5, which should be 0.1295: "<< myState.dist -> pdf(0.5) << std::endl; //this gives the wrong answer. Should give 0.1295, but instead gives 0.352.
//For myBoringClass, which works as I would expect
myBoringClass boringClass;
boringClass.x = 4;
std::cout << "Should be 2*4: " << boringClass.myBoringFunction(2) << std::endl; //prints 8
boringClass.x = 5;
std::cout << "Should be 2*5: " << boringClass.myBoringFunction(2) << std::endl; //prints 10
return 0;
}
You have member variables with the same name in the base (Distribution) and derived (NormalDistribution) classes. Remove the double param1, param2; from NormalDistribution.

Am I profiling this the right way ( C++ virtual functions )

I wanted to give up virtual functions in favor to function pointers, so I did some profiling, and here is how did it.
What I am trying to do, is decide whether to use virtual functions, or function pointers as in( int (*fcnPtr)(int); ) to achieve polymorphism.
Run time Polymorphism 1:
Just use virtual functions.
Run time Polymorphism 2 ( What I think is slightly fast, but bad design ):
Create a function pointer, like ( int (*fcnPtr)(int); ) as member variable.
Now each child class defines it own function pointer.
Call the function pointer, in the non virtual base function fct()
Now you have one direct method calling multiple functions.
This will result in two calls, one for the direct method, then the function pointer, that will be redefined in each child class.
even there are two calls, it's still faster than the virtual functions by ( 120 ms ), for 10 * 1000 * 1000 calls, and for 1000 child class, I think it's due to the virtual function lookups, if I am not mistaken, it has to look up the right class between 1000 classes in this case to call the right function.
I created a base class
void testFct()
{
int c = 0; c+=10;
}
class Base_Class{
public:Base_Class(){}
~Base_Class(){}
virtual void v_Fct() __attribute__ ((noinline)){ int c = 0; c+=10;
void fct() __attribute__ ((noinline)){ fcnPtr(); }
void (*fcnPtr)() = testFct;
};
Then I generated a 1000 child classes like this.
class Child_Class_0: public Base_Class
{
public:
Child_Class_0(){}
virtual void v_Fct() __attribute__ ((noinline)){ int c = 0; c+=10;}
};
.
class Child_Class_1: public Base_Class
{
public:
Child_Class_1(){}
virtual void v_Fct() __attribute__ ((noinline)){ int c = 0; c+=10;}
};
I also generated a factory function like this, to create objects at run time:
Base_Class *createObj( int i )
{
switch ( i ) {
case 0:
return new Child_Class_0();
break;
case 1:
return new Child_Class_1();
break;
case ..:
case 999:
}
Here are the profiling functions:
void profileVirtuals( int classCount , qreal maxCalls )
{
qreal i = 0;
QElapsedTimer myTimer;
myTimer.start();
/// At this point , the compiler has no idea
/// which child class to instantiate
for ( ;i < maxCalls; ++i) {
int randChild = random( 0 , classCount );
Base_Class *cc = createObj( randChild );
if( cc ){
/// Call virtual function
cc->v_Fct();
delete cc;
}
/// Make sure we are not missing any calls
else
qDebug() << "NULL";
}
int elapsed = myTimer.elapsed();
qDebug() << "VIRTUAL Function Called : " << i << " times.";
qDebug() << "DONE : " << elapsed;
}
.
void profileDirects( int classCount , qreal maxCalls )
{
qreal i = 0;
QElapsedTimer myTimer;
myTimer.start();
/// At this point , the compiler has no idea
/// which child class to instantiate
for ( ;i < maxCalls; ++i) {
int randChild = random( 0 , classCount );
Base_Class *cc = createObj( randChild );
if( cc ){
/// Call direct function
cc->fct();
delete cc;
}
/// Make sure we are not missing any calls
else
qDebug() << "NULL";
}
int elapsed = myTimer.elapsed();
qDebug() << "DIRECT Function Called : " << i << " times.";
qDebug() << "DONE : " << elapsed;
}
Here is the main functions, where I call both the virtual functions and the direct functions 10 * 1000 * 1000 times each
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int classCount = 1000;
qreal maxCalls = 10 * 1000 * 1000;
profileVirtuals( classCount , maxCalls );
profileDirects( classCount , maxCalls );
return a.exec();
}
And what I get is for 10 * 1000 * 1000 calls , about a 120 ms difference ( Of course direct calls faster ). Not that significant difference after all
The code is in Qt framework, but can easily understood as standard C++.
I will update the question if there is something unclear, about what I just did, or trying to do.
Conclusion:
Polymorphism 1 is faster than Polymorphism 2, if there are fewer child classes around a 100 child class.
Polymorphism 2 is faster than Polymorphism 1, if there are lots of child classes, more than a 1000 child class, the vTable lookup is what slows it down.

I cannot get this code to compile-for an assignment (see comment after code)

I am using MSVS2013. The 'Point' objects are generating errors in the Rectangle.h file. That's as far as I've gotten. (I've marked the lines that are showing errors with: " /** <<---HERE **/ ") I've done several searches for class in class syntax, but I'm either asking the wrong question or not wording it correctly.
Thx,
Mark L. (you guys should prolly add a "newb" tag to that list at the bottom)
// Ch9.DRAFT-Point.h
#ifndef POINT_H
#define POINT_H
class Point
{
public:
Point(double = 0.0, double = 0.0); // constructor
//set functions & get functions
void setX(double);
void setY(double);
double getX();
double getY();
private:
double x; // 0.0 <= x <= 20
double y; // 0.0 <= y <= 20
}; //end class Point
#endif
// end Point.h
///////////////////////////////////////////////////////////////////////
/** THIS FILE IS THE PROBLEM **/
/** the object 'Point' is causing errors **/
// Ch9.DRAFT-Rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
#include "Point.h"
class Rectangle
{
public:
// default constructor
Rectangle(Point = Point(0.0,1.0), Point(1.0,1.0), /** <<<---HERE**/
Point(1.0,0.0), Point(0.0,0.0)); /** <<<---AND HERE**/
// set x, y, x2, y2 coordinates
void setCoord(Point, Point, Point, Point); /** <<<---AND HERE**/
double length(); // length
double width(); // width
void perimeter(); // perimeter
void area(); // area
bool square(); // square
private:
Point point1; /** <<<---AND HERE**/
Point point2; /** <<<---AND HERE**/
Point point3; /** <<<---AND HERE**/
Point point4; /** <<<---AND HERE**/
}; // end class Rectangle
#endif
// end Rectangle.h
///////////////////////////////////////////////////////////////////////
// Ch9.DRAFT-Point.cpp
// Member function definitions for class Point
#include "Ch9.DRAFT-Point.h"
Point::Point(double xCoord, double yCoord)
{
setX(xCoord); // functio setX()
setY(yCoord); // functio setY()
} // end Point constructor
// set x coordinate
void Point::setX(double xCoord)
{
x = (xCoord >= 0.0 && xCoord <= 20.0) ? xCoord : 0.0;
} // end setX()
// set y coordinate
void Point::setY(double yCoord)
{
y = (yCoord >= 0.0 && yCoord <= 20.0) ? yCoord : 0.0;
} // end setY()
// return x coodinate
double Point::getX()
{
return x;
} //end getX()
// return y coodinate
double Point::getY()
{
return y;
} //end getY()
// end Point.cpp
///////////////////////////////////////////////////////////////////////
// Ch9.DRAFT-Rectangle.cpp
// Member-function definitions for class Rectangle.
#include <iostream>
#include <iomanip>
#include <cmath>
#include "Rectangle.h"
using namespace std;
Rectangle::Rectangle(Point a, Point b, Point c, Point d)
{
setCoord(a, b, c, d); // function setCoord()
} // end Rectangle constructor
void Rectangle::setCoord(Point p1, Point p2, Point p3, Point p4)
{
// verify rectangle formed
if((p1.getY() == p2.getY() && p1.getX() == p4.getX()
p2.getX() == p3.getX() && p3.getY() == p4.getY()))
{
point1 = p1;
point2 = p2;
point3 = p3;
point4 = p4;
} // end if
else
{
cout<< "Coordinates do not form a rectangle!\n"
<< "Use default values.\n";
point1 = Point(0.0,1.0);
point2 = Point(1.0,1.0);
point3 = Point(1.0,0.0);
point4 = Point(0.0,0.0);
} // end else
} // setCoord()
void Rectangle::length( )
{
double side1 = fabs(point4.getY() - point1.getY()); // get side1
double side2 = fabs(point2.getX() - point1.getX()); // get side2
double length = (side1 < side2 ? side1 : side2);
return length;
} // end length()
void Rectangle::width( )
{
double side1 = fabs(point4.getY() - point1.getY()); // get side1
double side2 = fabs(point2.getX() - point1.getX()); // get side2
double width = (side1 < side2 ? side1 : side2);
return width;
} // end width()
void Rectangle::perimeter()
{
cout << fixed << "\nThe perimeter is " << setprecision(1)
<< 2 * (length() + width()) << endl;
} // end perimeter()
void Rectangle::area()
{
cout << fixed << "\nThe area is " << setprecision(1)
<< (length() * width()) << endl;
} // end area()
bool Rectangle::square()
{
return (fabs(point4.getY() - point1.getY()) ==
fabs(point2.getX() - point1.getX());
} // end square()
// end Rectangle.cpp
///////////////////////////////////////////////////////////////////////
// Ch9.DRAFT-Ex09_11.cpp
#include <iostream>
#include "Rectangle.h" // include definition of class Rectangle
using namespace std;
int main()
{
Point w(1.0,1.0);
Point x(5.0,1.0);
Point y(5.0,3.0);
Point z(1.0,3.0);
Point j(0.0,0.0);
Point k(1.0,0.0);
Point m(1.0,1.0);
Point n(0.0,1.0);
Point v(99.0,-2.3);
Rectangle rectangles[4]; // array of 4 rectangles
// output rectangles
for(int i = 0; i < 4; i++)
{
cout << "Rectangle" << i + 1 << ":\n";
switch (i) // init 4 rectangles
{
case 0: // 1st rectangle
rectangles[i] = Rectangle(z, y, x, w);
break;
case 1: // 2nd rectangle
rectangles[i] = Rectangle(j, k, m, n);
break;
case 2: // 3rd rectangle
rectangles[i] = Rectangle(w, x, m, n);
break;
case 3: // 4th rectangle
rectangles[i] = Rectangle(v, x, y, z);
break;
} // end switch
cout << "length = " << rectangles[i].length();
cout << "\nwidth = " << rectangles[i].width();
rectangles[i].perimeter();
rectangles[i].area();
cout << "The rectangle "
<< (rectangles[i].square() ? "is" : "is not")
<< "a square.\n";
} // end for
return 0;
} // end main
// end Ex09_11.cpp
///////////////////////////////////////////////////////////////////////
/**********************************************************************
Chapter 09 exercise instructions:
Do exercise 9.12 on page 429 for 100 points.
This exercise makes a reference to Exercise 9.11. Here is the code for Exercise 9.11: Ex09_11.zip
DO NOT click drag the code into your new project. The code MUST be copied and pasted into new .h/.cpp files which you create. If you drag copy code into your project and then send it to me it probably will not contain that code!! This means you WILL have a rectangle class (Rectangle.h and Rectangle.cpp) and a file called Ex09_11.cpp that has your main function.
Before submitting your project check your archive and be sure it contains your .h and .cpp files.
I will be looking for the following in your program.
*Your program MUST use Cartesian coordinates (x and y coordinates for a total of eight coordinates per figure, each corner of your rectangle is an x,y coordinate). This is a major modification of the supplied code.
*You must follow my previous instructions regarding how to start your program. What you are doing is editing the supplied code so instead of the class Rectangle using width and length it will use cartesian coordinates as defined above.
*Do not have the user enter the coordinates. Hard code them into your program.
*You must include a default constructor for the rectangle class. The default constructor should have the following coordinates ( point 1:(0,0), point 2:(0,1), point 3:(1,1), point 4:(1,0). Be sure the constructor has the set function as described in the textbook assignment. I recommend you pass these points as eight integers (0,0,0,1,1,1,1,0).
*Your program must instantiate four objects of the Rectangle class.
•Your first object should not form a square using your supplied coordinates.
•Your second object should form a square using your coordinates.
•Your third object should should not be instantiated with any points allowing your default constructor points to be used
Hint: Remember that your constructor header can contain default values. If you create an object without passing values those default values will be used. See example program in chapter.
•Your fourth object should not form a rectangle and the default coordinates should replace your original coordinates.
The textbook assignment asks for a set function that tests if any coordinates are over 20. You do not have to write that function.
Do include a function that gets called to check if your coordinates form a square or rectangle as mentioned in the textbook assignment.
Keep your code simple. To decide if the rectangle is a square compare its height verses width.You choose which points and values to compare. If length = width is a square.
This is a programming project intended to show that you know how to program functions and understand constructors..
Review my supplied image of the program's output as a guide.
If you submit the code that I am supplying you will receive zero points.
*AGAIN, do not have the user make the coordinate entries. Code it into the program.
**************************************************************************/
This is not syntacticaly correct...
Rectangle(Point = Point(0.0,1.0), Point(1.0,1.0), /** <<<---HERE**/
Point(1.0,0.0), Point(0.0,0.0)); /** <<<---AND HERE**/
This would be better (and please name your params)
Rectangle(Point first = Point(0.0,1.0), Point second = Point(1.0,1.0), Point third = Point(1.0,0.0), Point fourth = Point(0.0,0.0));
BTW, looking at the comment at the end, it seems to indicate that you did not understand the goal of the project :)
This is a programming project intended to show that you know how to
program functions and understand constructors..
The following code just looks wrong to me.
// default constructor
Rectangle(Point = Point(0.0,1.0), Point(1.0,1.0), /** <<<---HERE**/
Point(1.0,0.0), Point(0.0,0.0)); /** <<<---AND HERE**/
try:
// default constructor
Rectangle(Point a = Point(0.0,1.0), Point b = Point(1.0,1.0),
Point c = Point(1.0,0.0), Point d = Point(0.0,0.0));
This is a programming project intended to show that you know how to program functions and understand constructors..
note you know how to... NOTthe stack overflow community knows how to
ask for help with an error message dont just post all code and ask whats wrong
but try having a look at some C++ tutorials about constructors and initialization

Does this code follow the definition of recursion?

I have a piece of code which I am doubting it as a implementation of recursion by its definition. My understanding is that the code must call itself, the exact same function. I also question whether writing the code this way adds additional overhead which can be seen with the use of recursion. What are your thoughts?
class dhObject
{
public:
dhObject** children;
int numChildren;
GLdouble linkLength; //ai
GLdouble theta; //angle of rot about the z axis
GLdouble twist; //about the x axis
GLdouble displacement; // displacement from the end point of prev along z
GLdouble thetaMax;
GLdouble thetaMin;
GLdouble thetaInc;
GLdouble direction;
dhObject(ifstream &fin)
{
fin >> numChildren >> linkLength >> theta >> twist >> displacement >> thetaMax >> thetaMin;
//std::cout << numChildren << std::endl;
direction = 1;
thetaInc = 1.0;
if (numChildren > 0)
{
children = new dhObject*[numChildren];
for(int i = 0; i < numChildren; ++i)
{
children[i] = new dhObject(fin);
}
}
}
void traverse(void)
{
glPushMatrix();
//draw move initial and draw
transform();
draw();
//draw children
for(int i = 0; i < numChildren; ++i)
{
children[i]->traverse();
}
glPopMatrix();
}
void update(void)
{
//Update the animation, if it has finished all animation go backwards
if (theta <= thetaMin)
{
thetaInc = 1.0;
} else if (theta >= thetaMax)
{
thetaInc = -1.0;
}
theta += thetaInc;
//std::cout << thetaMin << " " << theta << " " << thetaMax << std::endl;
for(int i = 0; i < numChildren; ++i)
{
children[i]->update();
}
}
void draw(void)
{
glPushMatrix();
glColor3f (0.0f,0.0f,1.0f);
glutSolidCube(0.1);
glPopMatrix();
}
void transform(void)
{
//Move in the correct way, R, T, T, R
glRotatef(theta, 0, 0, 1.0);
glTranslatef(0,0,displacement);
glTranslatef(linkLength, 0,0);
glRotatef(twist, 1.0,0.0,0.0);
}
};
This is a matter of definition/nitpicking. In this C function:
void traverse( tree * t ) {
if ( t != 0 ) {
traverse( t->right );
traverse( t->left );
}
}
Is the function recursive? I would say yes, even though it is being called on different objects. So I would say your code is also recursive. To take an even more extreme example:
unsigned int f( unsigned int n ) {
if ( n = 0 ) {
return 0;
}
else {
return f( n - 1 ); // XXX
}
}
The thing the function is being called on at XXX is obviously not the same thing it was originally called on. But I think everyone would agree this is a recursive function.
Yes, since you have certain functions calling themselves. By definition that is direct recursion. You could also have indirect recursion if you had function A() calling function B(), function B() in turn (directly or indirectly) calling function A() again.
Looks like recursion in the traverse() and update() methods with depth controlled by the physical geometry of your object collection.
If this is your actual class I would recommend a few things:
Check the upper bound of numChildren before using it lest someone passes in a remarkably huge number by mistake.
If this will be used in a threaded environment you might want to synchronize access to the child objects.
Consider using containers instead of allocating an array. I don't see a destructor either so you'd leak the memory for the array storage and the children if this object gets deleted.
If all you're worried about is the overhead of recursion then the important thing is to measure how deep your stack goes. It doesn't matter whether you're working recursively or not, if your stack is 100 calls deep.
Calling one of these methods(traverse or update) will have the effect of calling that same method an every child. So, the methods are not recursive. Instead, it's a recursive algorithm: it is applied recursively on the logical tree of objects.
The depth of the call stack is directly determined by the structure of the data on which the algorithm operates.
What really happens is this(pseudo code):
Function Traverse(object o)
{
[do something with o]
Foreach(object child in o.Children)
Traverse(child);
[do something with o]
}