A
Andrew.Morgan
Hi
I have three classes TDigest, THash and TSHA1.
//---------------------------------------------------------------------------
class TDigest
{
public:
// Constructors.
TDigest(int Count);
TDigest(const TDigest &Source);
// Destructors.
~TDigest();
// Operators.
TDigest& operator=(const TDigest &Source);
unsigned char& operator[](const int Index);
// Functions.
int Count();
private:
int count;
unsigned char *v,illegal;
};
TDigest has a variable length dynamic array, and is the return type of
THash:igest() and its descendants. The operator[] provides
access to the individual bytes that make up the hash.
//---------------------------------------------------------------------------
class THash
{
public:
// Constructors.
THash();
THash(const THash &Source);
// Destructors.
virtual ~THash();
// Operators.
THash& operator=(const THash &Source);
// Functions.
virtual void Init(unsigned int Count);
virtual void Block(char* Block);
virtual TDigest Digest();
protected:
unsigned int count;
virtual void Process();
};
THash is the base class for implementing a family of hash algorithms.
//---------------------------------------------------------------------------
class TSHA1ublic THash
{
public:
// Constructors.
TSHA1();
TSHA1(const TSHA1 &Source);
// Destructors.
~TSHA1();
// Operators.
TSHA1& operator=(const TSHA1 &Source);
// Functions.
void Init(unsigned int Count);
void Block(char* Block);
TDigest Digest();
protected:
unsigned int blocks,expand[80],work[5],hash[5],round[4];
void Process();
};
TSHA1 produces the SHA-1 hash for the supplied blocks of data.
My dilemma begins when trying to return the digest.
The following works, but has the overhead of temporaries with
associated constructor and destructor calls.
TDigest THash:igest()
{
TDigest digest(20); // setup 160-bit digest.
int index = 0;
for...
for...
digest[index++] = ...
return digest;
}
What I would prefer to do is:
TDigest* THash:igest()
{
TDigest digest = new TDigest(20); // setup 160-bit digest.
int index = 0;
for...
for...
digest[index++] = ...
return digest;
}
However, at the digest[index++] point, how does the compiler
distinguish between an array of TDigest objects, or the operator[] to
access a specific byte of the digest's internal array? In this case,
the compiler appears to assume that an array of objects has been
created (which seems odd to me since there was no "new TDigest[count]"
involved) and generates code to access the index-th digest object,
which does not exist beyond 0 (digest is digest[0]).
The following works:
digest[0][index++] = ...
but is non-intuitive. The non-intuitive problem persists since:
....
TDigest *result = sha.Digest();
for(int i = 0; i < result->Count(); i++)
{
... = result[0];
}
Unfortunately, references do not help either, since the compiler
errors:
"Attempting to return a reference to a local variable 'result'"
I had hoped that my Meyers' or Sutter's texts would shed some light on
this, but I am still in the dark.
Thanks in advance.
Andrew
I have three classes TDigest, THash and TSHA1.
//---------------------------------------------------------------------------
class TDigest
{
public:
// Constructors.
TDigest(int Count);
TDigest(const TDigest &Source);
// Destructors.
~TDigest();
// Operators.
TDigest& operator=(const TDigest &Source);
unsigned char& operator[](const int Index);
// Functions.
int Count();
private:
int count;
unsigned char *v,illegal;
};
TDigest has a variable length dynamic array, and is the return type of
THash:igest() and its descendants. The operator[] provides
access to the individual bytes that make up the hash.
//---------------------------------------------------------------------------
class THash
{
public:
// Constructors.
THash();
THash(const THash &Source);
// Destructors.
virtual ~THash();
// Operators.
THash& operator=(const THash &Source);
// Functions.
virtual void Init(unsigned int Count);
virtual void Block(char* Block);
virtual TDigest Digest();
protected:
unsigned int count;
virtual void Process();
};
THash is the base class for implementing a family of hash algorithms.
//---------------------------------------------------------------------------
class TSHA1ublic THash
{
public:
// Constructors.
TSHA1();
TSHA1(const TSHA1 &Source);
// Destructors.
~TSHA1();
// Operators.
TSHA1& operator=(const TSHA1 &Source);
// Functions.
void Init(unsigned int Count);
void Block(char* Block);
TDigest Digest();
protected:
unsigned int blocks,expand[80],work[5],hash[5],round[4];
void Process();
};
TSHA1 produces the SHA-1 hash for the supplied blocks of data.
My dilemma begins when trying to return the digest.
The following works, but has the overhead of temporaries with
associated constructor and destructor calls.
TDigest THash:igest()
{
TDigest digest(20); // setup 160-bit digest.
int index = 0;
for...
for...
digest[index++] = ...
return digest;
}
What I would prefer to do is:
TDigest* THash:igest()
{
TDigest digest = new TDigest(20); // setup 160-bit digest.
int index = 0;
for...
for...
digest[index++] = ...
return digest;
}
However, at the digest[index++] point, how does the compiler
distinguish between an array of TDigest objects, or the operator[] to
access a specific byte of the digest's internal array? In this case,
the compiler appears to assume that an array of objects has been
created (which seems odd to me since there was no "new TDigest[count]"
involved) and generates code to access the index-th digest object,
which does not exist beyond 0 (digest is digest[0]).
The following works:
digest[0][index++] = ...
but is non-intuitive. The non-intuitive problem persists since:
....
TDigest *result = sha.Digest();
for(int i = 0; i < result->Count(); i++)
{
... = result[0];
}
Unfortunately, references do not help either, since the compiler
errors:
"Attempting to return a reference to a local variable 'result'"
I had hoped that my Meyers' or Sutter's texts would shed some light on
this, but I am still in the dark.
Thanks in advance.
Andrew