oop — Что такое мономорфный класс C ++ и будет ли это примером?

Скажите, пожалуйста, является ли следующий класс мономорфным?

Что делает его мономорфным? Что на самом деле означает мономорфность?

class Foo
{
public:
Foo(int n)
{
this->m = n;
}

void print()
{
std::cout << this->m << std::endl;
}

private:
int m;
};

Редактировать:

в контексте класса Boo:

class Boo
{
public:
Boo& Boo::operator=(const Boo &boo)
{
*foo1 = *boo.foo1;
*foo2 = *boo.foo2;

return *this;
}

private:
Foo* foo1;
Foo* foo2;
};

-5

Решение

Во-первых, чтобы ответить на этот вопрос, нам нужно выяснить, что monomorphic действительно значит. Для этого давайте разберем слово:

мономорфный

Итак, если мы предположим, что моно = один а также морфический = трансформируемый (по крайней мере, для этого примера — не убивайте меня из-за семантики словаря)

Таким образом, мы можем принять это к значению многих вещей, вот некоторые из них в моей голове:

  1. Наш класс может быть изменен только один раз
  2. Или это может быть использовано как противоположность полиморфизму (то есть, его нельзя разделить на подклассы)
  3. Наконец, это может относиться к свойству математики: http://en.wikipedia.org/wiki/Monomorphism

Итак, если предположить, что этот ответ 3 — это не то, что мы ищем (в этом случае вам придется найти лучший ответ, потому что эта статья сбивает с толку), давайте рассмотрим один и два.

1. Наш класс может быть изменен только один раз

На мой взгляд, это наиболее вероятный смысл. На первый взгляд, ваш объект мономорфный, это означает, что он может быть изменен только один раз, через конструктор (будь то назначенный конструктор или встроенный конструктор копирования).

На любом компьютере, который имеет память для чтения-записи, это не может быть правдой, потому что почти всегда есть способ вручную установить биты в памяти, если вы хотите / нуждаетесь в этом.

Однако, если не учитывать этот сценарий, используя предоставленный вами интерфейс, то да, ваш класс мономорфный в том, что это член (m) устанавливается только через конструктор.

2. Наш класс не полиморфный

Ответ на этот вопрос немного сложен. C ++, в отличие от большинства языков, имеет две формы полиморфизма. В традиционном смысле ОО, он имеет возможность создавать функции, которые перезаписываются подклассом, который будет помечен как virtual, Однако вы этого не делаете, поэтому ОО полиморфизм невозможен в вашем классе.

Однако, как я сказал ранее, в C ++ доступно более одного типа полиморфизма. Второй тип упоминается как template polymorphism или же function polymorphism, который используется в STL (в основном для итераторов) и работает примерно так:

template<typename aImpl>
void printA(const aImpl &a)
{
a.print();
}

class A {
public:
void print() { puts("I'm in A!"); }
};

Это совершенно правильный интерфейс, и он будет работать как положено. Однако ничто не мешает поместить следующий класс в функцию:

class B {
public:
void print() { puts("I'm in B!"); }
};

Который, очевидно, напечатает другое значение.

В конце концов, C ++ является сложным языком, и если вы действительно хотите, чтобы класс не был полиморфным, вам нужно, чтобы все члены и функции были частными, что в первую очередь противоречит цели иметь объект.

7

Другие решения

Я наткнулся на эту статью, в которой термин «мономорфный» используется в контексте языка C ++, Анатомия оператора присваивания с 1997 года. Этот термин, по-видимому, редко используется в других местах, что подразумевает, что он, возможно, плавал в кругах C ++ в течение 90-х годов, но не получил большой тяги и больше не используется. В статье говорится:

Вопрос в следующем:

Рассмотрим следующее определение класса:

class TFoo : public TSuperFoo {
TBar* fBar1;
TBar* fBar2;
// various method definitions go here...
}

У тебя есть класс, TFoo, который происходит от класса, TSuperFoo, а также
который имеет два члена данных, оба из которых являются указателями на объекты
учебный класс TBar, Для целей этого упражнения рассмотрим оба указателя
иметь собственную семантику и TBar быть мономорфный класс. Написать
оператор присваивания для этого класса.

Глядя на различные определения в словаре, корень «морфический» чаще всего определяется как «имеющий определенную форму или форму», за которым следует некоторое указание на то, что он обычно используется с некоторым префиксом, таким как поли (полиморфный) или гомо (гомоморфный).

Префикс «моно» чаще всего определяется как «одиночный» или «один» или «одинокий» и обычно используется с некоторым суффиксом, таким как «плоскость» (моноплан или плоскость с одним крылом) или «рельс» (монорельс или одиночный рельс или трек).

В этом контексте, а также в том, что кажется вопросом, «мономорфный» (однокорпусный) используется как противоположность «полиморфного» (многогранный). Мономорфный класс — это класс, который не используется в качестве базового класса для какого-либо другого класса и не является производным от другого класса.

Более строгое определение мономорфного класса состоит в том, что класс должен также использовать только мономорфные классы или встроенные типы данных. Мономорфный класс не должен содержать никаких полиморфных классов как часть его определения или поведения.

Это поднимает вопрос о том, может ли строгий мономорфный класс содержать шаблонные переменные или методы. Моя первая интуиция заключается в том, что, пока шаблон создает мономорфный класс, это нормально. Другими словами, если компилятор пишет для вас мономорфный класс, это то же самое, что если бы Салли в кабинке вниз по строке написала это.

Так что, возможно, строгое определение должно исключать полиморфизм во время выполнения?

Так что казалось бы, что по первому, менее строгому определению мономорфного класса класс Foo в вопросе является мономорфным, потому что он не является производным от любого другого класса, и при этом он не имеет virtual деструктор, намекая на то, что он не предназначен для использования для получения другого класса, и при этом он не имеет каких-либо virtual методы.

Однако он использует std::cout в print() метод и std::cout определенно полиморфный. Так что, возможно, было бы точнее утверждать, что это полумономорфный класс, поскольку он использует полиморфный класс?

Казалось бы, мономорфный класс стоит один. Однако как мы можем написать класс так, чтобы он стоял один, и компилятор пометит любую попытку получить другой класс из этого класса.

C ++ позволяет классу быть суперклассом других классов, выводя новый класс из существующего класса. Существует ряд порой очень сложных правил о том, что возможно, как полиморфизм работает успешно, однако, в конце концов, используя final Ключевое слово (C ++ 11) с классом — это единственный разумный способ сделать класс, из которого другой класс не может быть получен.

Хотя просмотр немного я нахожу эту статью, Имитация финального класса в C ++, который обеспечивает метод с использованием private конструктор и virtual наследование.

/* A program without any compilation error to demonstrate that instances of
the Final class can be created */
#include<iostream>
using namespace std;

class Final;

class MakeFinal
{
private:
MakeFinal() { cout << "MakeFinal constructor" << endl; }
friend class Final;
};

class Final : virtual MakeFinal
{
public:
Final() { cout << "Final constructor" << endl; }
};

int main(int argc, char *argv[])
{
Final f;
return 0;
}
1

По вопросам рекламы [email protected]