GENERATED_BODY() causing function declaration and member inaccessibility errors

I have declared a copy constructor and an assignment operator (=) for a class in the .h file and defined it in the .cpp file. On building, the compiler throws an error saying “UCGenome::UCGenome(const UCGenome& g) member function already defined or declared” (for the copy constructor, similar error for assignment operator too), followed by a note that says “see declaration of UCGenome::UCGenome” and points to the line GENERATED_BODY(). I am pretty sure I have declared the function only once in the in the .h file. What am I supposed to do to fix this?
Moreover, on creating an object of the UCGenome class in another file, I am unable to access the private members of the class. The assignment operator is unable to access private members. Kindly provide a fix for this too.

I am using the assignment operator to equate two objects of class UCGenome. So basically by saying object1 = object2, I want to assign the values of member variables of object2 to the corresponding members of object1.

is there any way to check ue4’s implementation of copy constructors and assignment operators? Also, how do i eliminate the error of the inaccessibility of class members. I am creating an object of class UCGenome in another class UCSpecies. But this object is unable to access its own members. Even though I have declared the constructors and assignment operators in ■■■■■ scope, it considers it to be a private member.

The GENERATED_BODY() macro probably already defines the copy constructor and assignment operator. Since UE4 has its own system of life cycle built onto the C++ way to do things you can’t do stuff exactly as you would in standalone c++ code. I don’t know what exactly you would do in an assignment operator (other than the stock behaviour of course), but you can check this out for more information on copy construction. You can of course always just use normal methods to achieve things if the operators are already taken, but as I said, I don’t know with what kind of behaviour you would extend the assignment operator: If you just want the “normal” behaviour know: It is already defined for you.

1 Like

Ok so this is just standard behaviour. I did a bit of research myself, and it seems like the GENERATED_BODY() macro declares the method, but does not define it. So you should be fine by just deleting the declaration in your .h file, but leaving the definition in your .cpp file.

Thank you for the reply.
I removed the declarations of the copy constructor and assignment operator from the .h file. This eliminated the multiple declaration error. But the error of inaccessibility of private member still persists.
" ‘UCGenome::operator =’ cannot access private member declared in class ‘UCGenome’ "
This is the error i get. Similarly for the copy constructor I get " ‘UCGenome::UCGenome’ cannot access private member declared in class ‘UCGenome’ ".

How do I fix this?

I am unable to attach .cpp and .h files here. And the code is too long to post here. Is it possible to email the code to you?
Kindly share your email id and I shall immediately mail the files in question.
Thank you.

Please post your code so I can take a look at it.

When you write a comment there are several symbols above the window where you type. The one with the ones and zeros is specifically for posting code. You can paste your stuff in there.

just paste your definition of the assignment operator in there. I don’t need your whole class :smiley:

Can you also post your headerfile? (at least the part with variables). Your code looks ok, the only thing that comes to my mind is that maybe one of your members doesn’t have an assignment operator defined. This may cause the error.

Yeah but it’s causing the number of characters to exceed the limit.

//------------------------------------------------------------
//Copy Constructor
//------------------------------------------------------------
UCGenome::UCGenome(const UCGenome& g)
{
m_GenomeID = ;
m_vecNeurons = g.m_vecNeurons;
m_vecLinks = g.m_vecLinks;
m_pPhenotype = NULL; //no need to perform a deep copy
m_fFitness = g.m_fFitness;
m_fAdjustedFitness = g.m_fAdjustedFitness;
m_iNumInputs = g.m_iNumInputs;
m_iNumOutputs = g.m_iNumOutputs;
m_fAmountToSpawn = g.m_fAmountToSpawn;
}

//------------------------------------------------------------
//Assignment Operator
//------------------------------------------------------------
UCGenome& UCGenome::operator =(const UCGenome& g)
{
	//self assignment guard
	if (this != &g)
	{
		m_GenomeID = ;
		m_vecNeurons = g.m_vecNeurons;
		m_vecLinks = g.m_vecLinks;
		m_pPhenotype = NULL;	//no need to perform a deep copy
		m_fFitness = g.m_fFitness;
		m_fAdjustedFitness = g.m_fAdjustedFitness;
		m_iNumInputs = g.m_iNumInputs;
		m_iNumOutputs = g.m_iNumOutputs;
		m_fAmountToSpawn = g.m_fAmountToSpawn;
	}

	return *this;
}

This is all the private members of the class.

private:

	//its identification number
	int m_GenomeID;

	//all the neurons which make up this genome
	TArray<FNeuronGene> m_vecNeurons;

	//and all the links
	TArray<FLinkGene> m_vecLinks;

	//pointer to its phenotype
	UCNeuralNet* m_pPhenotype;

	//the depth of this genome's network
	int m_iNetDepth;

	//its raw fitness score
	float m_fFitness;

	//its fitness score after it has been placed into a
	//species and adjusted accordingly
	float m_fAdjustedFitness;

	//the number of offpsprings this individual is required
	//to spawn for the next generation
	float m_fAmountToSpawn;

	//keeps a record of the number of inputs and outputs
	int m_iNumInputs;
	int m_iNumOutputs;

	//keeps a track of which species this genome is in
	int m_iSpecies;

	//returns true if the specified link is already part of the genome
	bool DuplicateLink(int NeuronIn, int NeuronOut);

	//given a neuronid this function just finds its position in m_vecNeurons
	int GetElementPos(int neuron_id);

	//tests if the passed ID is the same as any existing neuron IDs.
	//Used in AddNeuron
	bool AlreadyHaveThisNeuronID(const int ID);

Public members shown below

public:

	UCGenome();

	UCGenome(int id, int inputs, int outputs);

	UCGenome(int id,
		TArray<FNeuronGene> neurons,
		TArray<FLinkGene> genes,
		int inputs,
		int outputs);

	~UCGenome();

	//copy constructor
//	UCGenome(const UCGenome& g);

	//assignment operator
//	UCGenome& operator =(const UCGenome& g);

	UFUNCTION(BlueprintCallable, Category = NEAT)
		UCNeuralNet* CreatePhenotype();

	UFUNCTION(BlueprintCallable, Category = NEAT)
		void DeletePhenotype();

	UFUNCTION(BlueprintCallable, Category = NEAT)
		void InitializeWeights();

		void AddLink(float MutationRate,
			float ChanceOfRecurrent,
			UCInnovation &innovation,
			int NumTrysToFindLoop,
			int NumTrysToAddLink);

		void AddNeuron(float MutationRate,
			UCInnovation &innovation,
			int NumTrysToFindOldLink);

	UFUNCTION(BlueprintCallable, Category = NEAT)
		void MutateWeights(float mut_rate,
			float prob_new_mut,
			float fMaxPerturbation);

	UFUNCTION(BlueprintCallable, Category = NEAT)
		void MutateActivationResponse(float mut_rate,
			float MaxPerturbation);

	float GetCompatibilityScore(const UCGenome &genome);

	UFUNCTION(BlueprintCallable, Category = NEAT)
	void SortGenes();

	bool Write(ostream &file);
    	bool CreateFromFile(const char* szFileName);

	//overload '<' used for sorting. From fittest to poorest
	friend bool operator <(const UCGenome& lhs, const UCGenome& rhs)
	{
		return (lhs.m_fFitness > rhs.m_fFitness);
	}

No. The errors are not occurring with UCNeuralNet objects. They’re occurring with UCGenome objects.

error C2248: ‘UCGenome::operator =’: cannot access private member declared in class ‘UCGenome’

So do you have assignment operators /copy constructors for UCNeuralNet FLinkGene and FNeuronGene?

on which line does that error happen?

Ok but where are the errors in your original two methods? It’s not really usefull to jump around classes now. Where do the errors occur in the UGenome constructor and assignment operator?

The error occurs on multiple lines. For example, the copy constructor error occurs for this line and the constructor definition in another file called CSpecies

UCGenome Leader()const { return m_Leader; }

UCSpecies::UCSpecies(UCGenome &FirstOrg,
	int SpeciesID) :m_iSpeciesID(SpeciesID),
	m_fBestFitness(FirstOrg.Fitness()),
	m_iGensNoImprovement(0),
	m_iAge(0),
	m_Leader(FirstOrg), //copy constructor error here
	m_fSpawnsRqd(0)
{
	m_vecMembers.Add(&FirstOrg);
	m_Leader = FirstOrg; //assignment operator error
}

The error shows up in similar locations in the rest of the file