c++ compile error ( copy constructor )

Started by
4 comments, last by Zahlman 18 years ago
Hello all, Visual Studio is giving me an error when I am attempting to push_back() an instance of my TestPolyData class onto a vector. The error message is: c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\vector(810): error C2558: class 'TestPolyData' : no copy constructor available or copy constructor is declared 'explicit' I am not sure why it is giving me this. I do have a copy constructor, and it is a public method. I don't have anything declared 'explicit', I am not sure what that means. Has anyone seen this before, or know what might be causing my issue? The header for TestPolyData is below.




#ifndef TESTPOLYDATA_H 
#define TESTPOLYDATA_H

#include "Common.h"

struct SATINTERVAL
{
	bool collisionExists;	// if this is false, then we don't care about the other data
	bool collisionInfinite;  // this is true in cases where the shapes will never collide, or will alawys collide
	float intervalLow;	// this is the smallest value where the shapes collide( or sometimes, the smallest extent along an axis )
	float intervalHigh;		// this is the largest value where the shapes collide( or sometimes, the largest extent along an axis )
	D3DXVECTOR3 lastAxisPassed;	// this axis is the normal of the final plane of separation crossed before the shapes start to overlap

	/// test data
	int collideAttemptNum;	// used for enumerating collision attempts in log data
	///
};

class TestPolyData
{

public:
	
	TestPolyData( D3DXVECTOR3 points[], int pointCount, D3DXVECTOR3 edges[], int edgeCount, D3DXVECTOR3 normal );
	TestPolyData( TestPolyData &orig );
	~TestPolyData();
	SATINTERVAL SATPolyPolyMinDist( TestPolyData &sourcePoly, D3DXVECTOR3 &motionDir, int collideAttemptNum=0 );
	void printInputs( TestPolyData &sourcePoly, int collideAttemptNum );
	

private:

	SATINTERVAL SATTestSepPlane( TestPolyData &sourcePoly, D3DXVECTOR3 &planeNormal, float motionNormalComponent );
	SATINTERVAL planeExtentMinMax( D3DXVECTOR3 &planeNormal );
	SATINTERVAL intervalIntersection( SATINTERVAL &interval1, SATINTERVAL &interval2 );
	SATINTERVAL intervalUnion( SATINTERVAL &interval1, SATINTERVAL &interval2 );

	D3DXVECTOR3 *m_pPoints;
	int m_PointCount;
	D3DXVECTOR3 *m_pEdges;
	int m_EdgeCount;
	D3DXVECTOR3 m_Normal;

	/// test data
	std::ofstream outfile2;
	///

};

#endif // !defined( TESTPOLYDATA_H )

Advertisement
The reference parameter to your copy constructor needs to be const. The copy operation is not supposed to modify the object being copied, and in some cases a mutable (non-const) object is not available; so the requirement is for a const reference.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Thanks, that solved that error.

Although it looks like being an insertable type into a vector requires quite a few other defined functions that I don't have. =, !=, etc.

I may want to look at another way of storing instances of my class =(
Quote:Original post by jujumbura
Although it looks like being an insertable type into a vector requires quite a few other defined functions that I don't have. =, !=, etc.


The only requirements on a type T used to instatiate a std::vector is that T is CopyConstructible and Assignable. If the implementation of std::vector has any other requirements other than those explcitily state in section 23.1 of the standard, you need to toss it out and find a conforming implementation.

Stephen M. Webb
Professional Free Software Developer

Your problem is your member std::ofstream variable. std::ofstream is non-copyable (what would it mean to open a file for writing and write something to it, then make a copy of the file and write different data to the original and the copy?) and thus the compiler is unable to generate a default copy-constructor and copy-assignment operator. Prefer to hold your std::ofstream member by (smart) pointer instead of by value.

Σnigma
Better yet, prefer not to hold it as a member at all. This doesn't appear to be any kind of logging class, so presumably you only need the stream for some kind of serialization function - in which case you should declare a local within that function (being given a filename) or accept one as a parameter - or better yet, do your outputting idiomatically by overloading the free-function operator<<:

// The usually recommended wayfriend ostream& operator<<(ostream& os, const TestPolyData& tpd) {  // output members of tpd to os here...  return os;}// You can avoid the need for a 'friend' declaration by re-implementing it in// terms of a member function. Now you have an extra way of doing things, but// wrote correspondingly extra code. The encapsulation/"good OO practice"// benefits here are highly controversial either way...void TestPolyData::printTo(ostream& os) const {  // output members of tpd to os here...}ostream& operator<<(ostream& os, const TestPolyData& tpd) {  tpd.printTo(os);  return os;}// With either of these approaches, users can now do 'cout << myTestPoly' for// example - or similarly with an already-opened file stream, etc.

This topic is closed to new replies.

Advertisement