Thread: inheritance - constructor

  1. #16
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    All very valid questions. You won't find much code where vectors are annotated with their orientation. A vector is an n-tuple of numbers, period. Everything else is typically up to interpretation.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  2. #17
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Separate the class declarations (and only the declarations) into a header file, include a forward declaration for Vector1_2:
    Code:
    #ifndef FOO_H
    #define FOO_H
    
    class Vector1_2;
    
    class Vector2_1
    {
    protected:
    	double a, b;
    public:
    	Vector2_1();
    	Vector2_1(double vec1, double vec2);
    	void SetSpecificValue(double value, int pos);
    	double GetSpecificValue(int pos) const;
    	virtual void print();
    	Vector1_2 transpose();
    	Vector2_1 operator / (const double& C);
    };
    
    
    
    class Vector1_2:public Vector2_1
    {
    public:
    	Vector1_2();
    	//Vector1_2(double vec1, double vec2) {Vector2_1(vec1,vec2);}
    	Vector1_2(double vec1, double vec2);
    	//Vector1_2 operator * (const Matrix2_2&) const;
    	void print();
    	Vector2_1 transpose();
    };
    #endif
    Then just include the header in your source file and write the code for the classes in that source file:
    Code:
    #include "foo.h"
    
    Vector2_1::Vector2_1() {a=0; b=0;}
    
    Vector2_1::Vector2_1(double vec1, double vec2):a(vec1), b(vec2) {}
    
    void Vector2_1::print()
    {
        std::cout<<std::endl<<"["<<a<<" "<<b<<"]T"<<std::endl;
    }
    
    Vector1_2 Vector2_1::transpose()
    {
        return Vector1_2(a,b);
    }  //the problem
    
    
    Vector1_2::Vector1_2() {Vector2_1();}
    
    Vector1_2::Vector1_2(double vec1, double vec2) {a=vec1; b=vec2;}
    
    void Vector1_2::print()
    {
        std::cout<<std::endl<<"["<<a<<" "<<b<<"]"<<std::endl;
    }
    
    Vector2_1 Vector1_2::transpose()
    {
        return Vector2_1(a,b);
    }
    I've commented out some stuff related to things that you did not provide code for, e.g. the Matrix object, so I could test that it would at least compile under this new design. Something like the above should at least compile. Not commenting on any other issues which may or may not be present...
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  3. #18
    Registered User
    Join Date
    Dec 2007
    Posts
    49
    Quote Originally Posted by anon View Post
    I'm sorry for not being very familiar with these things but...

    What is the difference between Vector1_2 and Vector2_1 and why is one inherited from the other and not, perhaps, the other way round.? (Especially seeing that transpose should return the other for both.)

    As I see the only difference is that one prints "T" in addition to the common things, and methods are rather randomly distributed between the two. Couldn't you put a bool in there to show that it is or isn't transposed? (Does it even matter if it is transposed? Wouldn't it be up to the user to decide what the vector represents?)
    I had to do so because multiplication of vector to a matrix is by the proper dimensions. Therefore, in order to overload operators correctly, I assume that I have to have two different classes. The problem is that I can't find a way to create a function that will give me the other type each time.

    I tried your offer, and built a base class vector2D that the two others vector2_1 and vector1_2 inherit from. It created a huge mass...And didn't solve the problem yet. Thank you anyway.

    Anyone?

  4. #19
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I think rather than trying to make transpose return a different object with the exact same internal data, you should just have a single Vector class.

    If you think that this data is so important you could add a member variable which shows how the vector should be multipltied with the matrix. Your transpose function might toggle this variable (return a copy with the value toggled).

    Or you might give up the attempt to overload operator *. If it is a regular (member) function you can simply pass another parameter telling it how to multiply.

    If I'm not mistaken vectors can be multiplied with several things and in several ways and if you used * for everything the user code may not become very clear at all.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #20
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    In all vector * matrix multiplications, the vector is assumed to be vertical. Otherwise, the matrix would have to be one column wide, i.e. a vertical vector. Since that isn't useful, this case is disregarded.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #21
    Registered User
    Join Date
    Dec 2007
    Posts
    49
    Quote Originally Posted by CornedBee View Post
    In all vector * matrix multiplications, the vector is assumed to be vertical. Otherwise, the matrix would have to be one column wide, i.e. a vertical vector. Since that isn't useful, this case is disregarded.
    But what about vector*vector?
    Either you'll get a scalar or a matrix n*n...

  7. #22
    Registered User
    Join Date
    Dec 2007
    Posts
    49
    Another question. If I have some class, and I want to do

    Class something(yada, yada, yada);
    int i=5;
    double b = i/something;

    How do I say in the operator overloading that the input of the operator is supposed to be behind it?

    Thanks.

  8. #23
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Regarding your overloading question, make the operator a free function and you can order the argument however you want.

    Regarding vector*vector, usually the distinction is made between dot product and cross product. One results in a scalar, the other in a vector. I've never heard of vector*vector -> matrix being actually used.
    Which product to use for operator * differs between libraries.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #24
    Registered User
    Join Date
    Dec 2007
    Posts
    49
    Quote Originally Posted by CornedBee View Post
    Regarding your overloading question, make the operator a free function and you can order the argument however you want.

    Regarding vector*vector, usually the distinction is made between dot product and cross product. One results in a scalar, the other in a vector. I've never heard of vector*vector -> matrix being actually used.
    Which product to use for operator * differs between libraries.
    If you have two 2D vectors, one is a(2X1) the other b(1X2).

    axb=matrix(2x2)
    bxa=number...


    My problem is as follows. Consider the following situation

    b x matrix x a

    b is a(transpose).
    I have a class called vector2D that contains vector<double> and a bool for transpose or not. (As default it's a column).
    The problem is, if I try to do

    b x matrix x b.transpose()

    inside the method transpose() I need to return a vector2D with its boolian for transposed converted to true. Because this flag is private I can't access it from instance b...


    Header
    Code:
    class Vector2D
    {
    private:
    	vector<double> vec;
    	bool transposeState;
    public:
    	Vector2D();
    	Vector2D(double vec1, double vec2);
    	~Vector2D();
    	void SetVectorItems(double vec1, double vec2);
    	void SetSpecificValue(double value, int pos);
    	double GetSpecificValue(int pos) const;
    	virtual void print();
    	Vector2D transpose(); //problem 1
    	Vector2D operator / (const double& C);
    	Matrix2_2 operator * (const Vector2D& vec); //problem 2 here
    	double operator * (const Vector2D& vec); //and here
    };
    CPP
    Code:
    Vector2D Vector2D::transpose() 
    {
    	vector<double> vec2(*this);
    	//now I need to change vec2 flag to true
    	return vec2;
    }
    The second problem is that if I do multiplication between two vectors I either need to return matrix or double...How can I do that?! The compiler can't tell which of the two to call!
    Last edited by misterowakka; 01-18-2008 at 04:51 AM.

  10. #25
    Registered User
    Join Date
    Dec 2007
    Posts
    49

    Exclamation Kalman Filter

    For whoever might need it. I had to create this matrix class for dealing with kalman filter. Since you helped me so much in this forum I soppuse that the final working code belongs to everyone.

    Header file

    Code:
    #include <vector>
    #include <iostream>
    using namespace std;
    
    class Matrix2_2;
    class Vector1_2;
    
    class Vector2_1
    {
    protected:
    	double a, b;
    public:
    	Vector2_1();
    	Vector2_1(double vec1, double vec2);
    	void SetSpecificValue(double value, int pos);
    	double GetSpecificValue(int pos) const;
    	virtual void print();
    	Vector1_2 transpose() const;
    	Vector2_1 operator / (const double& C);
    	Matrix2_2 operator * (const Vector1_2& vec);
    	Vector2_1 operator * (const double& num);
    	Vector2_1 operator + (const Vector2_1&) const;
    };
    
    class Vector1_2:public Vector2_1
    {
    public:
    	Vector1_2():Vector2_1() {}
    	Vector1_2(double vec1, double vec2):Vector2_1(vec1, vec2) {}
    	Vector1_2 operator * (const Matrix2_2&) const;
    	double operator * (const Vector2_1& vec) const;
    	void print();
    	Vector2_1 transpose() const;
    };
    
    class Matrix2_2
    {
    private:
    	double M11, M12, M21, M22;
    public:
    	Matrix2_2();
    	Matrix2_2(double UPLEFT, double UPRIGHT, double DOWNLEFT, double DOWNRIGHT):M11(UPLEFT), M12(UPRIGHT), M21(DOWNLEFT), M22(DOWNRIGHT) {}
    	Matrix2_2(const Matrix2_2& M2);
    	void SetAllValues(double UPLEFT, double UPRIGHT, double DOWNLEFT, double DOWNRIGHT);
    	void SetSpecificValue(double value, int row, int column);
    	double Getspecificvalue(int row, int column) const;
    	Matrix2_2 Transpose() const;
    	void print();
    
    	Matrix2_2 operator * (const Matrix2_2&) const;
    	Vector2_1 operator * (const Vector2_1&) const;
    	Matrix2_2 operator + (const Matrix2_2&) const;
    	Matrix2_2 operator - (const Matrix2_2&) const;
    };

    CPP
    Code:
    #include "windows.h"
    #include "Matrix.h"
    
    
    /////////////////VECTOR2_1//////////////////
    
    Vector2_1::Vector2_1() 
    {a=0; b=0;}
    
    Vector2_1::Vector2_1(double vec1, double vec2)
    {a=vec1; b=vec2;}
    
    void Vector2_1::SetSpecificValue(double value, int pos)
    {
    	if(pos==1)
    		a=value;
    	else if(pos==2)
    		b=value;
    	else
    		MessageBox(NULL, "wrong way of dealing with Vector2_1 class", "Located in: void Vector2_1::SetSpecificValue", NULL);
    }
    
    double Vector2_1::GetSpecificValue(int pos) const
    {
    	if(pos==1)
    		return a;
    	else if(pos==2)
    		return b;
    	else
    		MessageBox(NULL, "wrong way of dealing with Vector2_1 class", "Located in: void Vector2_1::SetSpecificValue", NULL);
    	return -99999; //error
    }
    
    
    void Vector2_1::print() 
    {cout<<endl<<"["<<a<<" "<<b<<"]T"<<endl;}
    
    Vector1_2 Vector2_1::transpose() const
    {
    	return Vector1_2(a,b);
    }
    
    Vector2_1 Vector2_1::operator / (const double& C)
    {
    	return Vector2_1(a/C, b/C);
    }
    
    Matrix2_2 Vector2_1::operator * (const Vector1_2& vec)
    {
    	return Matrix2_2(a*vec.GetSpecificValue(1), a*vec.GetSpecificValue(2), b*vec.GetSpecificValue(1), b*vec.GetSpecificValue(2));
    }
    
    
    Vector2_1 Vector2_1::operator * (const double& num)
    {
    	return Vector2_1(a*num, b*num);
    }
    
    
    Vector2_1 Vector2_1::operator + (const Vector2_1& vec2) const
    {
    	return Vector2_1(a+vec2.GetSpecificValue(1), b+vec2.GetSpecificValue(2));
    }
    
    
    /////////////////VECTOR1_2//////////////////
    
    
    Vector1_2 Vector1_2::operator * (const Matrix2_2& M) const
    {
    	Vector1_2 vec2;
    	vec2.SetSpecificValue(a*M.Getspecificvalue(1,1)+b*M.Getspecificvalue(2,1),1);
    	vec2.SetSpecificValue(a*M.Getspecificvalue(1,2)+b*M.Getspecificvalue(2,2),2);
    	return vec2;
    }
    
    
    double Vector1_2::operator * (const Vector2_1& vec) const
    {
    	return a*vec.GetSpecificValue(1)+b*vec.GetSpecificValue(2);
    }
    
    
    void Vector1_2::print() 
    {cout<<endl<<"["<<a<<" "<<b<<"]"<<endl;}
    
    Vector2_1 Vector1_2::transpose() const
    {
    	return Vector2_1(a,b);
    }
    
    
    
    
    
    
    
    /////////////////MATRIX2_2//////////////////
    
    Matrix2_2::Matrix2_2()
    {
    	M11=0; M12=0; M21=0; M22=0;
    }
    
    Matrix2_2::Matrix2_2(const Matrix2_2& M2) 
    {
    	*this=M2;
    }
    
    void Matrix2_2::SetAllValues(double UPLEFT, double UPRIGHT, double DOWNLEFT, double DOWNRIGHT)
    {
    	M11=UPLEFT; M12=UPRIGHT; M21=DOWNLEFT; M22=DOWNRIGHT;
    }
    
    void Matrix2_2::SetSpecificValue(double value, int row, int column)
    {
    	if(row==1)
    		if(column==1)
    			M11=value;
    		else if(column==2)
    			M12=value;
    		else
    			MessageBox(NULL, "wrong way of dealing with Matrix2_2 class", "Located in: void Matrix2_2::SetSpecificValue", NULL);
    	else if(row==2)
    		if(column==1)
    			M21=value;
    		else if(column==2)
    			M22=value;
    		else
    			MessageBox(NULL, "wrong way of dealing with Matrix2_2 class", "Located in: void Matrix2_2::SetSpecificValue", NULL);
    	else
    		MessageBox(NULL, "wrong way of dealing with Matrix2_2 class", "Located in: void Matrix2_2::SetSpecificValue", NULL);
    }
    
    
    double Matrix2_2::Getspecificvalue(int row, int column) const
    {
    	if(row==1)
    		if(column==1)
    			return M11;
    		else if(column==2)
    			return M12;
    		else
    			MessageBox(NULL, "wrong way of dealing with Matrix2_2 class", "Located in: void Matrix2_2::SetSpecificValue", NULL);
    	else if(row==2)
    		if(column==1)
    			return M21;
    		else if(column==2)
    			return M22;
    		else
    			MessageBox(NULL, "wrong way of dealing with Matrix2_2 class", "Located in: void Matrix2_2::SetSpecificValue", NULL);
    	else
    		MessageBox(NULL, "wrong way of dealing with Matrix2_2 class", "Located in: void Matrix2_2::SetSpecificValue", NULL);
    	return -999999;//for error
    }
    
    
    Matrix2_2 Matrix2_2::operator + (const Matrix2_2& M2) const
    {
    	Matrix2_2 M3;
    	M3.SetSpecificValue(M11+M2.Getspecificvalue(1,1),1,1);
    	M3.SetSpecificValue(M12+M2.Getspecificvalue(1,2),1,2);
    	M3.SetSpecificValue(M21+M2.Getspecificvalue(2,1),2,1);
    	M3.SetSpecificValue(M22+M2.Getspecificvalue(2,2),2,2);
    	return M3;
    }
    
    
    Matrix2_2 Matrix2_2::operator - (const Matrix2_2& M2) const
    {
    	Matrix2_2 M3;
    	M3.SetSpecificValue(M11-M2.Getspecificvalue(1,1),1,1);
    	M3.SetSpecificValue(M12-M2.Getspecificvalue(1,2),1,2);
    	M3.SetSpecificValue(M21-M2.Getspecificvalue(2,1),2,1);
    	M3.SetSpecificValue(M22-M2.Getspecificvalue(2,2),2,2);
    	return M3;
    }
    
    Matrix2_2 Matrix2_2::operator * (const Matrix2_2& M2) const
    {
    	Matrix2_2 mat;
    	mat.SetSpecificValue(M11*M2.Getspecificvalue(1,1)+M12*M2.Getspecificvalue(2,1), 1,1);
    	mat.SetSpecificValue(M11*M2.Getspecificvalue(1,2)+M12*M2.Getspecificvalue(2,2), 1,2);
    	mat.SetSpecificValue(M21*M2.Getspecificvalue(1,1)+M22*M2.Getspecificvalue(2,1), 2,1);
    	mat.SetSpecificValue(M21*M2.Getspecificvalue(1,2)+M22*M2.Getspecificvalue(2,2), 2,2);
    	return mat;
    }
    
    Vector2_1 Matrix2_2::operator * (const Vector2_1& vec) const
    {
    	Vector2_1 vec2;
    	vec2.SetSpecificValue(M11*vec.GetSpecificValue(1)+M12*vec.GetSpecificValue(2), 1);
    	vec2.SetSpecificValue(M21*vec.GetSpecificValue(1)+M22*vec.GetSpecificValue(2), 2);
    	return vec2;
    }
    
    
    
    void Matrix2_2::print()
    {
    	cout<<endl<<M11<<" "<<M12<<endl<<M21<<" "<<M22<<endl<<endl;
    }
    
    Matrix2_2 Matrix2_2::Transpose() const
    {
    	return Matrix2_2(M11,M21,M12,M22);
    }

    Kalman filter implementation using these classes
    Code:
    #include "Matrix.h"
    #include <iostream>
    using namespace std;
    
    void main()
    {
    
    	double vel[8]={1,2,3,4,5,6,7,8};
    	for (int counter=0; counter<8; counter++)
    	{
    		static Vector2_1 Xhat_previous(2,2);
    		const Matrix2_2 A(1,1,0,1);
    		
    		Vector2_1 XhatPre=A*Xhat_previous;
    		//XhatPre.print();
    		
    		static Matrix2_2 P_previous(1,2,3,4);
    		const Matrix2_2 Q(5,6,7,8);
    		const double R=0.1666666;
    		
    		Matrix2_2 Ppre=A*P_previous*A.Transpose()+Q;
    		//Ppre.print();
    		
    		const Vector1_2 H(0,1);
    		
    		Vector2_1 K = (Ppre*H.transpose())/((H*Ppre*H.transpose())+R);
    		//K.print();
    
    		Vector2_1 Xhat=XhatPre+K*(vel[counter]-H*XhatPre);
    		Xhat.print();
    
    		Xhat = Xhat_previous;
    
    		const Matrix2_2 I(1,0,0,1);
    		Matrix2_2 P=(I-K*H)*Ppre;
    		P.print();
    
    		P = P_previous;
    	}
    	//return Xhat.GetSpecificValue(1); //this is the calculated velocity from kalman filter. Hhat[2] is the acceleration
    }

  11. #26
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Now that I see you're including Windows.h, you could use precompiled headers.
    Put windows.h in stdafx.h and enable PCH in project options under compiler (create PCH first, then use PCH).
    It will speed up compile time significantly.

    And I see you're using void main too >_<
    Undefined! Use int main!
    Last edited by Elysia; 01-18-2008 at 01:07 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #27

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 06-10-2008, 08:38 PM
  2. C++ have a constructor call another constructor
    By QuestionC in forum C++ Programming
    Replies: 4
    Last Post: 05-17-2007, 01:59 AM
  3. How do I override constructor in inheritance?
    By Loduwijk in forum C++ Programming
    Replies: 13
    Last Post: 03-24-2006, 09:36 AM
  4. Constructor inheritance
    By Hunter2 in forum C++ Programming
    Replies: 9
    Last Post: 07-14-2004, 10:13 AM
  5. Constructor inheritance
    By Jasel in forum C++ Programming
    Replies: 3
    Last Post: 12-10-2003, 10:43 AM