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;
}