无聊,瞎写

以下内容瞎猜瞎写,不太懂java,懂点C++, 闲极无聊写点东西

学java的时候,看到java中函数参数的传递方式是按值传递,即使参数是对象,传递的也是对象的引用的拷贝,感觉比较有意思,这让我感觉Java中的对象,有点像C++中不能解引用的指针,并且java 中的对象基本都过new 在堆上操作的,又有种被阉割的C++的感觉。

所以,突然就想自己建立一个小的体系,来阉割一下C++, 模仿一下java,最后跑题了。

  • 像java一样所有的类继承一个超类,新建父类Object ,让所有的子类继承它, 应为java的多态是默认的,我们将所有的方法标记virtual
class Object
{
public:

    virtual std::string toString()
    {
        return std::string("Object");
    }
    virtual long long hasCode()
    {
        return -1;
    }   
    virtual void* clone()
    {
        return new Object {*this} ;
    }
    virtual int equals(void* obj)
    {
        return 0;
    }

    
};

这些方法徒有其形,意思意思而已。

  • 像java一样将对象建立在堆上, 为了禁止人们在栈上创建对象,我选择将所有的构造方法(不考虑移动构造,省点字,其实是一开始忘了)用protected 保护起来,对外界不公开,这样人们无法手动在栈创在对象了,提供唯一的接口去提供创建对象,让用户只能选择在堆上建立对象
class Object
{
public:

    template
    static Object* create(Args... args)
    {
        return new Object{args...};
    }

    virtual std::string toString()
    {
        return std::string("Object");
    }

    virtual long long hasCode()
    {
        return -1;
    }   
    
    virtual void* clone()
    {
        return new Object {*this} ;
    }
    
    virtual int equals(void* obj)
    {
        return 0;
    }

protected:
    Object() = default;
    Object(const Object& obj) = default;
    Object& operator=(const Object&) = default;
    
};

开始跑题了

  • 至此我们的这个体系中的对象按照上述的约束,便只能在栈上创建了,但我感觉我们的类体系中,每创建一个类,都会写很多重复的代码, 构造函数 , 重载赋值, 以及create ,很没意思。我要偷个懒,
#define CREATE(cls) \
template \
static cls* create(Args... args) \
{\
    return new cls{args...};\
}

#define DEFAULT(cls) \
cls() = default; \
cls(const cls&) = default;\
cls& operator=(const cls&) = default;
  • 通过宏将Object 简化
class Object
{
public:

    CREATE(Object)
    virtual std::string toString()
    {
        return std::string("Object");
    }

    virtual long long hasCode()
    {
        return -1;
    }   
    
    virtual void* clone()
    {
        return new Object {*this} ;
    }
    
    virtual int equals(void* obj)
    {
        return 0;
    }

protected:
    DEFAULT(Object)

};
  • 让我们写个子类吧
class Integer extends Object
{
public:
    CREATE(Integer);

    int getValue() { return value; }
    void setValue(int value) { this->value = value; }
    
protected:

    Integer(int v)
    {
        value = v;
    }
    DEFAULT(Integer);

private:

    int value;
   

};
  • 感觉有点眼熟,extends, 是一个宏,我们定一些宏,让我们的体系更像是java
#define extends :public
#define interface class
#define import using namespace
  • 我突然有个新的担心,如果有别人把的类体系与别的混了咋办, 别人的有没有create, 和别人的混在一起,有时create, 有时new 的太乱,我要再提供一个统一的create 借口,适用所有的类
    template偏特化上场
template::value>
struct Alloc
{
    template
    static T* create(Args... args)
    {
        return T::create(args...);
    }
};

template
struct Alloc
{
    template
    static T* create(Args... args)
    {
        return new T{args...};
    }
};
  • 我为普通的类,我们为所有类统一了一个create的"函数",首先这个函数会检测这个类是普通类还是我们的类,判断依据比较糙, 是否含有create函数。这样对外统一了。但是怎么判断一个类有没有静态的create函数?SFINAE将展现他的强大
template
class has_create
{
private:

    template
    static auto check(int)-> decltype(U::create());

    template
    static char check(...);

public:
    using value_type = bool;
    constexpr static bool value = std::is_same(0))>::value;
};

  • 到这为止,没啥难点去实现统一的接口, 再通过模板偏特化,简简单单。我们可以为所有类在堆上的创建提供了一个统一的接口。
class A
{
};

class B
{
public:
    CREATE(B)
protected:
    DEFAULT(B);
};

int main()
{
    A* pa = Alloc::create();
    B* pb = Alloc::create();    
    return 0;

};

写着写着就跑题了,正好到了跑路时间,跑路,也正好把无聊时间打发了。

你可能感兴趣的:(无聊,瞎写)