-4

请告诉我,如果以下类是单态的?

是什么使它具有单态性?单态实际上是什么意思?

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

2 回答 2

7

首先,为了回答这个问题,我们需要检查monomorphic真正的含义。为此,让我们分解这个词:

单态

所以,如果我们假设mono = onemorphic = transformable(至少对于这个例子 - 不要因为字典语义而杀了我)

所以,我们可以把它理解为很多东西,这里有一些是我想不到的:

  1. 我们的班级只能换一次
  2. 或者它可以用作多态的对立面(意味着它不能被子类化)
  3. 最后,它可以参考数学的属性:http ://en.wikipedia.org/wiki/Monomorphism

因此,假设答案 3 不是我们正在寻找的(在这种情况下,您必须找到更好的答案,因为那篇文章令人困惑),让我们逐步介绍第一个和第二个。

1.我们的班级只能换一次

在我看来,这是最可能的意思。乍一看,您的对象是单态的,这意味着它只能通过构造函数(指定构造函数或内置复制构造函数)更改一次。

在任何具有读写内存的计算机中,这不可能是真的,因为如果您愿意/需要,几乎总有一种方法可以手动设置内存中的位。

但是,除非使用您提供的接口,否则您的类是单态的,因为它的成员 ( m) 仅通过构造函数设置。

2. 我们的类不是多态的

这个问题的答案有点复杂。与大多数语言不同,C++ 有两种形式的多态性。在传统的 OO 意义上,它能够创建被子类覆盖的函数,该子类将被标记为virtual. 但是,您不这样做,因此您的类不可能实现 OO 多态性。

然而,正如我之前所说,C++ 中有不止一种类型的多态性可用。第二种类型称为template polymorphismor 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++ 是一门复杂的语言,如果你真的想让一个类不能是多态的,你需要让所有的成员和函数都是私有的,这违背了拥有对象的初衷。

于 2012-09-24T12:04:02.033 回答
2

我遇到了这篇文章,其中术语“单态”在 C++ 语言的上下文中使用,从 1997 年开始的赋值运算符剖析。这个术语似乎很少在其他地方使用,这意味着它可能在 C++ 中浮动在 90 年代循环,但没有获得太大的牵引力,不再使用。文章指出:

问题如下:

考虑以下类定义:

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

你有一个类 ,TFoo它是一个类 的后代TSuperFoo,它有两个数据成员,它们都是指向类对象的指针TBar。出于本练习的目的,将两个指针都考虑为具有拥有语义和TBar态类。为这个类编写赋值运算符。

查看各种字典定义,最常见的词根“morphic”被定义为“具有特定形式或形状”,然后是一些指示它通常与某些前缀一起使用,例如 poly(多态)或 homo(同态)。

前缀“mono”最常被定义为“single”或“one”或“lone”,通常与一些后缀一起使用,例如“plane”(单翼或单翼飞机)或“rail”(单轨或单轨或追踪)。

在这种情况下以及似乎是问题的情况下,“单态”(单态)被用作“多态”(多态)的对立面。单态类是不用作任何其他类的基类也不从另一个类派生的类。

单态类的更严格定义是该类还必须仅使用单态类或内置数据类型。单态类不得包含任何多态类作为其定义或行为的一部分。

这确实提出了一个严格的单态类是否可以包含模板化变量或方法的问题。我的第一个直觉是,只要模板创建一个单态类就可以了。换句话说,如果编译器正在为您编写一个单态类,那么它就像是 Sally 在下排隔间中编写它一样。

那么也许严格的定义应该排除运行时多态性?

因此,通过第一个不太严格的单态类定义,Foo问题中的类似乎是单态的,因为它不是从任何其他类派生的,也没有virtual析构函数,暗示它不打算用于派生另一个类类,也没有任何virtual方法。

然而,它确实std::cout在该print()方法中使用,并且std::cout绝对是多态的。所以也许更准确地说这是一个半单态类,因为它使用了一个多态类?

看起来单态类是独立的。但是,我们如何编写一个类,使其独立,编译器将标记任何从该类派生另一个类的尝试。

C++ 允许一个类通过从现有类派生一个新类成为其他类的超类。关于什么是可能的,多态性如何成功工作,有时有许多非常复杂的规则,但是最终将final关键字(C++11)与一个类一起使用是唯一合理的方法来创建一个类,另一个类无法导出。

虽然浏览了一下,我发现这篇文章Simulating final class in 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;
}
于 2017-04-06T18:31:27.330 回答