Наследование в C++

Проблема возникает потому, что вы используете f-строку (f"> \n{l}") для форматирования текста и передаете переменную l в эту f-строку. Хотя ваша переменная l была установлена ​​в последний раз на последней итерации предыдущего цикла, вы печатаете последний элемент Y в вашем файле.

Правильный синтаксис был бы:

 with open("abc.txt", "w") as text_file:
     print(f'> \n{Y}', file=text_file) 

Или, может быть, это ваше отступление, и вы намеревались сделать это:

 for l in Y:
   print(l, end = '')

   with open("abc.txt", "w") as text_file:
     print(f'> \n{l}', file=text_file)

Кроме того, я бы порекомендовал вместо этого сделайте что-то вроде этого:

with open("abc.txt", "w") as f:
    for l in Y:
        f.write(f'> {l}\n')

Или даже лучше, если возможно:

with open("abc.txt", "w") as f:
    f.writelines(Y)
6
задан Hooked 6 March 2015 в 04:43
поделиться

6 ответов

Измените эту строку:

string ofxSndObj::createFilter(ofxBaseSndObj obj)

кому:

string ofxSndObj::createFilter(ofxBaseSndObj& obj)

То, что Вы делаете, является передающим значением (передающий копию).

Это означает копирование объекта в функцию. Поскольку функция не знает то, что вводит Вас, на самом деле передают его, только передает тип, определенный в объявлении функции, и таким образом это делает копию базового класса (это, знают как режущая проблема).

Решение состоит в том, чтобы передать ссылкой.

Если Вы не хотите, чтобы функция изменила объект (возможно, именно поэтому, Вы были передающими значением, таким образом, это не могло измениться, оригинал) затем передают ссылку константы.

class ofxBaseSndObj
{
    public:
        virtual string getType()  const;
        // If the method does not change the object mark it const

        string key;

};

string ofxSndObj::createFilter(ofxBaseSndObj const& obj)
{
    // allowed to call this if getType() is a const
    string str = obj.getType();

    if(str.compare("ofxSOBuzz") == 0)
    {
        printf(" all is well ");
    }
}
25
ответ дан 8 December 2019 в 02:22
поделиться

Создание конструктора копии и оператора = частный является эффективным способом предотвратить эту ошибку снова.

Например:

class ofxBaseSndObj {
public:
    virtual string getType(){}
    string key;

private:
    ofxBaseSndObj(const ofxBaseSndObj& rhs);
    ofxBaseSndObj& operator=(const ofxBaseSndObj& rhs);
};

Если нет никакого другого серьезного основания, необходимо использовать C++, создал в RTTI. Можно затем использовать оператор идентификатора типа. Посмотрите на свою документацию компиляторов для включения этого, если это не находится на по умолчанию.

2
ответ дан 8 December 2019 в 02:22
поделиться

Эту проблему называют, "режущий" в C++.

2
ответ дан 8 December 2019 в 02:22
поделиться

Другие решили режущую проблему. Вы затем просите хорошо, позволять мне сказать, я знаю, что должен сделать что-то для определения базового типа, но являюсь там чем-то более изящным, чем выполнение перечислимого поиска для определения вида наследованного объекта?

Запросы и включение типа объекта являются плохим дизайном, который упускает суть подхода OO.

Вместо

string ofxSndObj::createFilter(ofxBaseSndObj& obj)
{
    string str = obj.getType();
    if(str.compare("ofxSOBuzz") == 0)
    {
        // do ofxSOBuzz - specific thing
    }
    else if(str.compare("some other derived class") == 0)
    {
        // do stuff for other derived classes
    }
       // etc...
}

сделайте интересное поведение виртуальной функцией:

class ofxBaseSndObj {

public:
    // get rid of getType()
    virtual void HelpCreateFilter() = 0;
};


string ofxSndObj::createFilter(ofxBaseSndObj& obj)
{
    // Let the derived class do it's own specialized work.
    // This function doesn't need to know what it is.
    obj.HelpCreateFilter();
    // rest of filter creation
}

Почему это лучше, чем исходная версия? Поскольку ofxSndObj::createFilter не нуждается в изменении, если будущие производные классы ofxBaseSndObj добавляются к системе. Ваши потребности версии, расширяющиеся для каждого нового производного класса. Если это неясно, попытайтесь отправить немного больше кода - я не могу сказать из Ваших кодовых имен или имен классов, что эти функции, как предполагается, делают.

1
ответ дан 8 December 2019 в 02:22
поделиться

Необходимо передать экземпляр createFilter как указатель (или ссылка) к объекту. Вы являетесь передающими значением, и это заставляет компилятор копировать производный объект, который Вы используете в качестве аргумента в экземпляр базового класса. Когда это делает это, Вы теряете то, что это был первоначально производный тип.

Как написано Ваш код не должен на самом деле компилировать начиная с объявления ofxBaseSndObj:: getType ничего не возвращает. Вы имели в виду, чтобы это было абстрактным методом, или возвратите пустую строку?

При создании этого абстрактным методом затем, компилятор жаловался бы на попытку инстанцировать абстрактного класса в ofxSndObj:: метод createFilter.

10
ответ дан 8 December 2019 в 02:22
поделиться

Вы могли использовать dynamic_cast или type_id

-1
ответ дан 8 December 2019 в 02:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: