天天看點

d中正确建立類執行個體

​​原文​​

//c++
#include <iostream>
class A {
public:
  void foo() { std::cout << "foo" << std::endl; }
};
int main() {
  auto a1 = new A;
  a1->foo(); // prints "foo"
  A a2;
  a2.foo();  // prints "foo"
  delete a1;
}
//D 版:

@safe:
import std.stdio;
class A {
  void foo() { writeln("foo"); }
}
void main() {
  auto a1 = new A;
  a1.foo(); // 列印 "foo"
  A a2;
  a2.foo(); // 段錯誤.
}      

未用​

​@safe​

​,怎麼回事?

A a2;
a2.foo();
//約==C++的
A *a2 = NULL;
a2->foo();      

正确.​

​D​

​​中的類就像​

​Java​

​​中的類.​

​a2​

​​是​

​引用​

​​.另一方面,​

​構​

​​是確定與​

​C++​

​​中一樣的​

​值型​

​.

在D中,所有​

​引用和指針​

​​都預設​

​初化​

​​為​

​無效(null)​

​​,是以,如果在解引用時,不想​

​段錯誤​

​​,則必須​

​顯式​

​​配置設定​

​初值​

​.

import std.stdio:writeln;


void main(){
    int* a;
    writeln(*a); // 11信号幹掉它.
    int* b = new int();
    writeln(*b);
}      

​C++​

​​因為與​

​D構​

​​一樣,是​

​值類型​

​​,通過​

​預設​

​​構造器​

​初化​

​變量.

#include <iostream>

using namespace std;


class A{
    public:
    A(){
        this -> a = new int(44);
    }
    int* a;
};

int main()
{
    int* a;

    cout << *a << "\n"; //列印垃圾值

    A instance;
    cout << *instance.a  << "\n"; // 總是列印44
    return 0;
}      

使用​

​指針​

​​,會得到​

​同樣​

​不良行為.

#include <iostream>

using namespace std;


class A{
    public:
    A(){
        this -> a = new int(44);
    }
    int* a;
};

int main()
{
    int* a;

    cout << *a << "\n"; //列印垃圾值

    A* instance;
    cout << instance ->a  << "\n"; 
//未列印
    return 0;
}      

但是,如果使用​

​引用​

​​,則會收到一條​

​錯誤消息​

​​,而​

​D​

​​即使用​

​@安全​

​也不會提示.

#include <iostream>

using namespace std;


class A{
    public:
    A(){
        this -> a = new int(44);
    }
    int* a;
};

int main()
{
    int* a;

    cout << *a << "\n"; //列印垃圾值

    A& instance;
    cout << instance.a  << "\n";
// 未列印.
    return 0;
}//要報錯.      

​D的安全​

​:

import std.stdio:writeln;


void main() @safe {
    int* a;
    writeln(*a); // 段錯誤
    int* b = new int();
    writeln(*b);
}      

在D中,在堆上​

​配置設定​

​​所有​

​類執行個體​

​​,​

​類變量​

​​是引用它們.按​

​局部​

​​變量聲明​

​A​

​​的​

​執行個體​

​​,會初化為​

​空引用(無效null)​

​​,是以在其上​

​調用​

​​方法會正确地​

​段錯誤​

​​.

可在棧上配置設定​​

​類執行個體​

​:

scope Object o = new Object;      
import std.typecons : scoped;
import std.stdio;

class C {
    int i;
}

void main() {
    // 或這樣:
    // auto c = scoped!C();

    // 或這樣
    scope c = new C();

    writeln("如果關閉位址值,則對象在棧中");
    writeln(&c);
    writeln(&c.i);
}