C++ 成员指针是否应该在初始化时始终使用new?
在中,我在构造函数调用的方法中遇到了奇怪的分段错误,但显然没有其他方法(甚至在从C++ 成员指针是否应该在初始化时始终使用new?,c++,data-member-pointers,C++,Data Member Pointers,在中,我在构造函数调用的方法中遇到了奇怪的分段错误,但显然没有其他方法(甚至在从main()调用的codebarker::testvectorofements中也没有),其定义如下: void CodeBreaker::testVectorOfElements(int size) { // try to do what you did in makeNumericCodes with the vector while (this->numericCodes.size() &
main()
调用的codebarker::testvectorofements
中也没有),其定义如下:
void CodeBreaker::testVectorOfElements(int size)
{
// try to do what you did in makeNumericCodes with the vector
while (this->numericCodes.size() < size)
{
this->numericCodes.push_back(this->Z[0]);
}
}
IntegerGroup.cpp
IntegerRing.cpp
#包括“IntegerRing.h”
#包括“IntegerGroup.h”
#包括
IntegerRing::Element::Element()
:IntegerGroup::GroupElement()
{
}
IntegerRing::IntegerRing(int n)
:IntegerGroup::IntegerGroup(n)
{
}
IntegerRing::Element::Element(int m,IntegerGroup*g)
:IntegerGroup::GroupElement(m,g)
{
}
IntegerRing::Element::Element(常量IntegerGroup::GroupElement&el)
:IntegerGroup::GroupElement(el)
{
}
破译者
\ifndef CODEBREAKER\u H
#定义代码断路器
#包括
#包括
#包括
#包括
#包括“IntegerRing.h”
#包括“标点符号发生列表.h”
类破译器
{
公众:
破坏者();
代码断路器(标准::字符串和布尔);
元素的无效测试向量(int);
私人:
标点发生列表标点;
积分Z;
void initCharMap();
void makeNumericCodes();
int getNumericCodeFor(char)常量;
std::map charFrequencyMap;
std::矢量数字码;
字符串密文,明文;
std::字符串密码文件名;
};
#恩迪夫
CodeBreaker.cpp
#包括“CodeBreaker.h”
#包括
#包括
#include,问题是当我分配这些指针时是否应该使用new
?当创建IntegerRing
时,它会尝试创建IntegerRing::Elements
,并向其传递指向自身的指针(出于必要:环的数学定义要求它配备加法和乘法,该数学结构的元素使用该运算符).第一件事是IntegerGroup
应该有一个虚拟析构函数。为什么是虚拟析构函数?还有,为什么这个问题不好?@MikeWarren——原因是你是从基类派生的。如果其他人以多态方式使用你的类,当内存泄漏报告出现时,他们会对你非常生气。S对于MCVE来说,EEM不是最小值。首先,IntegerGroup
应该有一个虚拟析构函数。为什么是虚拟析构函数?还有,为什么这个问题不好?@MikeWarren——原因是你是从基类派生的。如果其他人以多态方式使用你的类,当内存丢失时,他们会对你非常生气eak报告来了,对MCVE来说似乎不是最小的。
#ifndef INTEGERGROUP_H
#define INTEGERGROUP_H
#include "Array.h"
#include <vector> // for some reason, this didn't work.
#include <iostream>
// This group is the integers mod n
// multiplication in integer group is simply integer addition modulo n
class IntegerGroup
{
public:
IntegerGroup();
IntegerGroup(int);
class GroupElement
{
protected:
int m;
IntegerGroup* group;
public:
GroupElement();
GroupElement(int);
GroupElement(int, IntegerGroup*);
~GroupElement();
};
int size() const;
protected:
int n;
Array<GroupElement> elements;
void createNewElement(int);
};
#endif
#include "IntegerGroup.h"
#include <new>
#include <iostream>
IntegerGroup::IntegerGroup()
{
}
IntegerGroup::IntegerGroup(int n)
: n(n), elements(Array<IntegerGroup::GroupElement>(n))
//elements(std::vector<IntegerGroup::GroupElement>(n))
{
//this is to have integers in [0,n-1]
for (int j = 0; j < n; j++)
{
this->createNewElement(j);
}
}
void IntegerGroup::createNewElement(int m)
{
// create new GroupElement
GroupElement newElement(m, this);
// store it at index m in elements
this->elements[m] = newElement;
}
IntegerGroup::GroupElement::GroupElement()
: group(0)
{
}
IntegerGroup::GroupElement::GroupElement(int x)
: m(x), group(0)
{
}
IntegerGroup::GroupElement::GroupElement(int m, IntegerGroup * g)
: group(g)
{
// this->m must be in [0, g->size() - 1], if g not null
if (g)
{
this->m = m % g->size();
if (this->m < 0) this->m = g->size() + this->m;
}
else
{
this->m = m;
}
}
IntegerGroup::GroupElement::~GroupElement()
{
if (this->group)
{
this->group = 0;
}
}
int IntegerGroup::size() const { return this->n; }
#ifndef INTEGERRING_H
#define INTEGERRING_H
#include "IntegerGroup.h"
class IntegerRing : public IntegerGroup
{
public:
IntegerRing();
IntegerRing(int);
IntegerRing(const IntegerGroup&);
class Element : public IntegerGroup::GroupElement::GroupElement
{
public:
Element();
Element(int, IntegerGroup*);
//~Element();
operator IntegerGroup::GroupElement() { return IntegerGroup::GroupElement(); }
Element(const IntegerGroup::GroupElement&);
};
};
#endif
#include "IntegerRing.h"
#include "IntegerGroup.h"
#include <iostream>
IntegerRing::Element::Element()
: IntegerGroup::GroupElement()
{
}
IntegerRing::IntegerRing(int n)
: IntegerGroup::IntegerGroup(n)
{
}
IntegerRing::Element::Element(int m, IntegerGroup * g)
: IntegerGroup::GroupElement(m, g)
{
}
IntegerRing::Element::Element(const IntegerGroup::GroupElement& el)
: IntegerGroup::GroupElement(el)
{
}
#ifndef CODEBREAKER_H
#define CODEBREAKER_H
#include <string>
#include <map>
#include <utility>
#include <vector>
#include "IntegerRing.h"
#include "PunctuationOccurrenceList.h"
class CodeBreaker
{
public:
CodeBreaker();
CodeBreaker(std::string&, bool);
void testVectorOfElements(int);
private:
PunctuationOccurrenceList punctuation;
IntegerRing Z;
void initCharMap();
void makeNumericCodes();
int getNumericCodeFor(char) const;
std::map<char, int> charFrequencyMap;
std::vector<IntegerRing::Element> numericCodes;
std::string ciphertext, plaintext;
std::string cipherFilename;
};
#endif
#include "CodeBreaker.h"
#include <iostream>
#include <fstream>
#include <algorithm>
CodeBreaker::CodeBreaker()
: Z(IntegerRing::IntegerRing(26)),
punctuation(PunctuationOccurrenceList::PunctuationOccurrenceList())
{
// initialize charFrequencyMap
this->initCharMap();
}
CodeBreaker::CodeBreaker(std::string& str, bool readFromFile)
: Z(IntegerRing::IntegerRing(26))
{
// if reading from file
if (readFromFile)
{
// str is filename to read from
// open file specified by str
std::ifstream input(str.c_str());
std::string line;
// read contents to ciphertext
while (std::getline(input, line))
{
this->ciphertext += line + "\n";
}
// close file
input.close();
}
// otherwise
else
{
// str is ciphertext itself
// write it to this->ciphertext
this->ciphertext = str;
}
// strip punctuation
this->punctuation = PunctuationOccurrenceList::PunctuationOccurrenceList(this->ciphertext);
// log numeric codes ('A' => 0, 'B' => 1, ... , 'Z' => 25)
this->makeNumericCodes();
}
void CodeBreaker::makeNumericCodes()
{
std::cout << "this->ciphertext.size() == " << this->ciphertext.size() << std::endl;
std::cout << "this->numericCodes.capacity() == " << this->numericCodes.capacity() << std::endl;
std::cout << "this->numericCodes.max_size() == " << this->numericCodes.max_size() << std::endl;
// if there isn't as many numeric codes as there are characters in ciphertext
while (this->numericCodes.size() < this->ciphertext.size())
{
std::cout << "Pushing dummy Element to numericCodes...\n";
this->numericCodes.push_back(this->Z[0]);
}
// for every character in ciphertext
for (int j = 0; j < this->ciphertext.size(); j++)
{
// if character's numerical code is not logged in numericCodes
int numericCode = this->getNumericCodeFor(ciphertext[j]);
if (numericCode != this->numericCodes[j].val())
// log it
this->numericCodes[j] = (IntegerRing::Element)this->Z[numericCode];
}
// while there are more numericCodes than characters in ciphertexts
while (this->numericCodes.size() > this->ciphertext.size())
// remove last character
this->numericCodes.pop_back();
}
void CodeBreaker::testVectorOfElements(int size)
{
// try to do what you did in makeNumericCodes with the vector
while (this->numericCodes.size() < size)
{
this->numericCodes.push_back(this->Z[0]);
}
}
int CodeBreaker::getNumericCodeFor(char c) const
{
// if character is in ['A', 'Z']
if ((c >= 'A') && (c <= 'Z'))
// return its int value minus 'A'
return (int)(c - 'A');
// otherwise, if it is in ['a', 'z']
if ((c >= 'a') && (c <= 'z'))
// return its int value minus 'a'
return (int)(c - 'a');
std::cout << "invalid character: " << c << std::endl;
return -1;
}
void CodeBreaker::initCharMap()
{
for (char c = 'A'; c <= 'Z'; c++)
{
this->charFrequencyMap[c] = 0;
}
}
#include <iostream>
#include <string>
#include "CodeBreaker.h"
//#include "IntegerRing.h"
using namespace std;
int main()
{
bool testInClass = true;
if (testInClass)
{
string str = "I'm plaintext, but deal with me anyways, because this is mock code.";
CodeBreaker c(str, false);
/*CodeBreaker d;
d.testVectorOfElements(64);*/
}
else
{
vector<IntegerRing::Element> a;
IntegerRing Z(26);
cout << "a.capacity == " << a.capacity() << endl;
while (a.size() < 2400)
{
a.push_back(Z[0]);
}
cout << "a.size() == " << a.size() << endl;
for (int j = 0; j < 26; j++)
{
cout << a[j] << " ";
}
cout << endl;
}
return 0;
}