Tạo một đối tượng có trạng thái thay đổi khi gán


31

Tôi thấy thật kỳ lạ khi điều này có thể xảy ra ở Ruby (Tôi sẽ không nói ngay lập tức như thế nào):

obj = #code redacted

print obj.state # Some value.

LValue = obj

print obj.state # Different value!

Thách thức của bạn là tạo mã đại khái của hình thức này. Tạo một đối tượng và gán nó cho một biến. Nó nên có một số thuộc tính được xác định (hoặc phương thức xác định, idempotent) như stateở trên, thay đổi sau khi đối tượng được gán cho một định danh mới ( LValueở trên), ngay cả khi bạn vẫn sử dụng định danh cũ ( objở trên) để tham chiếu đến nó.

Chỉnh sửa để nhấn mạnh : statehoặc tương đương phải là idempotent, do đó, việc tạo một trình truy cập sửa đổi giá trị hoặc vì bất kỳ lý do nào khác trả về kết quả khác nhau khi được gọi nhiều lần liên tiếp, không phải là một giải pháp hợp lệ. Hay đơn giản hơn, nó phải là bài tập thay đổi trạng thái.

Bất kỳ ngôn ngữ nào có sự phân công đều đủ điều kiện, mặc dù có thể có một số nơi không có giải pháp hoàn toàn hợp pháp. Tôi sẽ đăng câu trả lời Ruby của mình nếu không có ai nhận được câu trả lời sau vài ngày và chấp nhận câu trả lời được bình chọn cao nhất trên cơ sở.


Phải có LValue = objdòng cần thiết stateđể thực sự thay đổi? (Tôi chỉ có thể tạo một tài sản trong C # tăng lên mỗi khi bạn nhận được nó)
Tim S.

2
Vâng, đó là những gì tôi dự định bằng cách nói phương pháp cần thiết là bình thường. Tôi sẽ chỉnh sửa để làm cho rõ ràng hơn.
lịch sử

Được rồi cảm ơn. Tôi phải xem qua phần đó.
Tim S.

4
Đơn giản chỉ cần trả lại số tiền của công việc đối tượng?
Nick T

Thay đổi phá hủy đối với chính đối tượng? EmacsLisp: (setq a (list "val")) (setq b (nconc a "val2"))ví dụ. akết thúc đánh giá như ("val" . "val2")tại thời điểm đó.
Jonathan Leech-Pepin

Câu trả lời:


30

C ++

Điều này là tầm thường bằng cách sử dụng các công cụ phù hợp.

#include <iostream>

using namespace std;

class Obj {
public:
   int state;

   Obj& operator= (Obj& foo) {
      foo.state++;
      this->state = foo.state - 2;
      return *this;
   }
};

int main() {
   Obj a, b, c, d;
   a.state = 3;
   b.state = 4;

   cout << a.state << " " << b.state << "\n";

   c = a;
   d = b;

   cout << a.state << " " << b.state << " " << c.state << " " << d.state << "\n";

   return 0;
}

Đầu ra:

3 4
4 5 2 3

12
Khoảnh khắc tôi nhìn thấy tiêu đề, tôi biết ai đó sẽ làm quá tải toán tử. Đó là cách rõ ràng. Có một upvote.

17

PHP (bản dựng gỡ lỗi,> = 5,4)

Chúng tôi sử dụng refcount của đối tượng trong một getter. (Vì vậy, bằng cách chuyển nhượng, tổng số tăng và thay đổi giá trị)

class State {
    public function __get($arg) {
        ob_start();
        debug_zval_dump($this); // e.g. "object(State)#1 (0) refcount(6)"
        return ob_get_clean()[29];
    }
}

$obj = new State;
var_dump($obj->state);
$a = $obj;
var_dump($obj->state);

14

C #

Hai tùy chọn đơn giản:

class Obj
{
    public int state;
    public static implicit operator int(Obj o)
    {
        return o.state++;
    }
}

static int LValueI;
static Obj LValueM { set { value.state++; } }
static void Main()
{
    var obj = new Obj { state = 1 };
    LValueI = obj;
    Console.WriteLine(obj.state); //2, caused by the implicit cast.

    LValueM = obj;
    Console.WriteLine(obj.state); //3, caused by the property setter.
    Console.ReadLine();
}

Hoặc đơn giản là chúng ta có thể ghi vào cùng một bộ nhớ:

[StructLayoutAttribute(LayoutKind.Explicit)]
class Program
{
    [FieldOffset(0)]
    int state = 1;
    [FieldOffset(1)]
    int LValue;

    void Test()
    {
        var obj = this;

        Console.WriteLine(state);  //1
        LValue = state;
        Console.WriteLine(state);  //257
        Console.ReadLine();
    }
    static void Main() { new Program().Test(); }
}

12

TeX, ngắn hơn nhiều so với các câu trả lời khác ở đây

\setbox0=\hbox{Hello world!} % Put stuff in the box 0.
\message{\the\wd0}           % Print the width of the box => non-zero
\setbox2=\box0               % Put the box instead in box 2.
\message{\the\wd0}           % Now box 0 is void, hence has zero width.

Là một hệ thống sắp chữ, TeX có loại "hộp", chứa vật liệu sắp chữ. Vì trường hợp sử dụng phổ biến nhất là di chuyển vật liệu này, tách nó, v.v., thay vì tạo các bản sao của nó, các hộp thường bị xóa khi sử dụng (hay đúng hơn là các biến "hộp" là con trỏ và chỉ một con trỏ tại một thời điểm có thể trỏ đến một hộp thực tế trong bộ nhớ). Không cần bất kỳ phép thuật.


8

C ++ 11 (Vì vậy, các bạn đã quên về unique_ptr / shared_ptr :-))

#include <iostream>
#include <memory>
using namespace std;
int main() {
    std::unique_ptr<int> u1(new int(0)), u2;
    std::shared_ptr<int> s1 = std::make_shared<int>(0), s2;
    std::cout<<u1.get()<<" "<<u2.get()<<" "<<std::endl;
    std::cout<<s1.use_count()<<" "<<s2.use_count()<<" "<<std::endl;
    u2 = std::move(u1);
    s2 = s1;
    std::cout<<u1.get()<<" "<<u2.get()<<" "<<std::endl;
    std::cout<<s1.use_count()<<" "<<s2.use_count()<<" "<<std::endl;
   return 0;
}

7

Pháo đài 03

Điều này hơi giống với câu trả lời D của Hugo, nhưng ẩn hơn một chút (một phần vì ai là người # $% ^ biết đối tượng Fortran hướng đối tượng)?

module objects
   implicit none

   type ObjDef
      integer :: state
    contains
      procedure :: initObject
      procedure :: printObject
      procedure :: setNew
   end type
 contains
   subroutine initObject(this)
     class(ObjDef) :: this
     this%state = this%state + 1
   end subroutine initObject

   subroutine printObject(this)
     class(ObjDef) :: this
     print '(a,i0)',"this%state = ",this%state
   end subroutine printObject

   subroutine setNew(this,that)
     class(ObjDef) :: this,that
     that%state = this%state
   end subroutine setNew

end module objects

program objectChange
   use objects
   type(ObjDef) :: a,b

   call initObject(a)
   call printObject(a)
   call b%setNew(a)
   call printObject(a)
end program objectChange

Đầu ra là

this%state = 1
this%state = 0

Nếu bạn có thể tìm ra những gì đã xảy ra, điểm thưởng cho bạn! Nếu không:

Khi gọi thủ tục setNewtrong biểu mẫu call b%setNew(a), bmặc nhiên là đối số thứ nhất, không phải đối số thứ hai.


7

PowerShell

Điều này tạo ra một đối tượng có thuộc statetính là tên của các biến trỏ đến đối tượng.

$a = @{}| Add-Member -MemberType:16 -PassThru state -Value {
        (gv|?{$this -eq $_.Value}|%{$_.Name}) -join ','} 

'Before: ' + $a.state
$b = $a
'After: ' + $a.state

Đầu ra

Before: a,this
After: a,b,this

Lưu ý: Điều này không hoạt động nếu việc chuyển nhượng xảy ra trong phạm vi con.

'Before: ' + $a.state
&{$b = $a}
'After: ' + $a.state

Đầu ra

Before: a,this
After: a,this

Biến-biến là thông minh!
mê mẩn

5

Perl 5

Đây là một cách để làm điều đó trong Perl:

package Magic {
    sub new { bless {state => 1} }
    use overload '""' => sub { $_[0]{state}++ };
}
use feature 'say';

my $obj = new Magic;
say $obj->{state};
substr($_, 0) = $obj;
say $obj->{state};

Kết quả này:

1
2

Giải trình:

Đây là một ứng dụng đơn giản của quá tải . Cụ thể, tôi quá tải toán tử chuyển đổi chuỗi "", được gọi khi đối tượng quá tải được gán cho substr()(mà, vâng, là một giá trị pháp lý trong Perl).

Ngoài ra còn có rất nhiều biến số đặc biệt trong Perl, chuỗi số bất cứ thứ gì được gán cho chúng. Ví dụ, sau đây cũng hoạt động:

my $obj = new Magic;
say $obj->{state};
$0 = $obj;
say $obj->{state};

Giải pháp thay thế

Đây là một cách khác để làm điều đó:

package Magic {
    use Devel::Peek 'SvREFCNT';
    sub new { bless \my $foo }
    sub state { SvREFCNT ${$_[0]} }
}
use feature 'say';

my $obj = new Magic;
say $obj->state;
my $other = $obj;
say $obj->state;

Đây statelà một phương thức (chúng ta có thể biến nó thành một thuộc tính với các shenanigans liên kết / quá tải, nhưng điều đó sẽ làm phức tạp mọi thứ) theo nghĩa đen là đếm số lượng tham chiếu đến đối tượng. Do đó, không giống như trong giải pháp đầu tiên, bạn thực sự phải gán $objcho một biến bình thường có thể giữ một tham chiếu đối tượng để làm cho trạng thái thay đổi.


5

JavaScript

Ok, vì vậy tôi đã tạo một phiên bản ngắn hơn hoạt động như SSCCE, nhưng không còn cố phân tích JavaScript đúng cách, vì vậy việc đếm tham chiếu có thể không hoạt động khi được đặt trong một tập lệnh phức tạp hơn.

(function run () {
    var lineOne = getLine (1), a, b, x, y, z;
    var x = {
        get state () {
            var x=/([a-z]+)\s*=\s*([a-z]+)/,c;
            return 1 + Object.keys (c = run.toString ().split ('\n').slice (0,getLine (2)).filter (function (a) {return (x.test (a))}).reduce (function (a,b,c,d) {var r=b.match (x),t=r[2];while (a[t]){t=a[t]};a[r[1]]=t;return a}, {v:0})).reduce (function (a,b) {return (c[b]=="x"?1:0) + a},0)
        }
    };
    console.log (x.state);  //1
    console.log (x.state);  //1
    y = x;
    console.log (x.state);  //2
    z = y;
    console.log (x.state);  //3    
    a = z;
    b = a;
    console.log (x.state);  //5
    a = null;
    console.log (x.state);  //4
    b = null;
    console.log (x.state);  //3
})() //1 1 2 3 5 4 3 

function getLine(n) {
   try {
      to
   } catch (dat) {
      var stack = dat.stack.split('\n');
       for (var i = 0; i < stack.length; i++) {
           if (~stack[i].indexOf ('getLine')) break;          
       }
      return dat.stack.split ('\n')[i + ~~n].match (/:(\d+)/)[1] - ~~window.hasOwnProperty ('__commandLineAPI')
   }
}

2
Quan tâm để giải thích những gì bạn đang làm?
Ryan

5
... Thế giới này có gì? O_o
Doorknob

@Doorknob Một getter trả về kết quả, khi gọi một hàm, tính tần suất một tên người dùng được tham chiếu là rval, trong một biểu thức gán, trong một văn bản có sẵn cho đến một dòng nhất định, truyền nguồn hàm kèm theo của nó và dòng getter được gọi từ như là đối số. Mọi thứ khác là một mã thông báo chứng minh lộn xộn. --- Tôi không biết làm thế nào khác tôi nên gọi nó . Nói cách khác. Nói cách khác: getter đếm số lần gán các tham chiếu cho x cho đến dòng mà nó được gọi từ đó, phần còn lại là mã thông báo chưa hoàn thành.
C5H8NNaO4

1
Các bài dài nhất và rộng nhất!
Nicolas Barbulesco

1
@NicolasBarbulesco Tôi đã làm cho nó ngắn hơn
C5H8NNaO4

4

Con trăn

Đó là một chút gian lận, nhưng về:

import gc
class A(object):
    @property
    def state(self):
        return len(gc.get_referrers(self))

a = A()
print a.state
b = {"x": a}
print a.state
a.y = a
print a.state
del a
print b["x"].state

4

C ++ 11

mặc dù điều này có thể được mở rộng cho các ngôn ngữ khác hỗ trợ các hàm hủy ẩn / tường minh

#include <iostream>
using namespace std;

class Foo {
    int *ptr;
public:
    Foo() {
        ptr = new int(0);
    }   
    int state() {
        return *ptr;
    }
    ~Foo() {
        (*ptr)++;
    }
};
int main() {
    Foo a, b;
    cout << a.state() << " " << b.state() << "\n";
    {
        Foo c, d;
        c = a;
        d = b;
    }
   cout << a.state() << " " << b.state()  << "\n";

   return 0;
}

Toán tử gán mặc định thực hiện một bản sao nông. Vì vậy, đối tượng nhận vẫn sở hữu con trỏ và mọi thay đổi đều ảnh hưởng đến đối tượng ban đầu;


1
Vâng, newkhông có một deletetrong chương trình. Mặc dù, đối với nhiệm vụ này, tôi nghĩ nó đủ tốt rồi :)
Ruslan

Các đầu ra là gì?
Nicolas Barbulesco

1
Theo những gì tôi hiểu (C ++ ở rất xa), ở đây bài tập không thay đổi trạng thái . Nếu không, di chuyển coutdòng lên trước }và cho biết nếu điều đó làm việc. :-)
Nicolas Barbulesco

4

Scala

Chuyển đổi ngầm định cho phép bạn thực hiện điều này trong khi gán cho một biến cục bộ thông thường:

import scala.language.implicitConversions

class Obj {
  var counter = 0
}

implicit def o2s(x: Obj): String = {
  x.counter += 1
  x.toString
}

val obj = new Obj
println(obj.counter)
val s: String = obj
println(obj.counter)

Bạn cũng có thể thực hiện điều đó với các loại suy ra:

var s = ""
s = obj

Bạn cũng có thể sử dụng phương thức setter tùy chỉnh, mặc dù điều đó đòi hỏi giá trị L phải là một trường:

object L {
  var _value = new Obj
  def value = _value
  def value_=(x: Obj): Unit = {
    _value = x
    x.counter += 1
  }
}

val obj = new Obj
println(obj.counter)
L.value = obj
println(obj.counter)

3

D

struct Obj {
    int state;

    void opAssign (ref Obj other) {
        ++other.state;
    }
}

void main () {
    import std.stdio;

    Obj obj, lvalue;
    writeln(obj);
    lvalue = obj;
    writeln(obj);
}

Đầu ra:

Obj(0)
Obj(1)

3

Hồng ngọc

Như đã hứa, đây là câu trả lời đã truyền cảm hứng cho câu hỏi.

obj = Class.new { def self.state; to_s[/</] ? "Has not been assigned\n" : "Assigned to #{to_s}"; end }

print obj.state

LValue = obj

print obj.state

Class.newtạo ra một lớp ẩn danh. Gọi to_smột lớp ẩn danh cung cấp đại diện chuỗi mặc định của các đối tượng, trông giống như #<Class:0x007fe3b38ed958>. Tuy nhiên, một khi lớp đã được gán cho một hằng, to_strở thành hằng số đó. Trong Ruby, hằng số là một biến bắt đầu bằng chữ in hoa, do đó, objlà một tham chiếu đến lớp cho phép nó ẩn danh.

Mã của tôi kết thúc to_stheo một statephương thức, vì vậy đầu ra trở thành

Has not been assigned
Assigned to LValue

Không giống như hầu hết các giải pháp ở đây, điều này chỉ hoạt động một lần: gán objcho hằng số khác sẽ không thay đổi biểu diễn chuỗi của nó và sẽ không gán giá trị mới cho LValue.


3

Trong Java

Tôi nghĩ rằng điều này là không thể trong Java. Nhưng…

Lớp chính :

public class MyAppOfCats {

  public static void main(String[] args) {
    Cat tom = new Cat();
    System.out.println(tom.state()); 
    // Output : NOT-BEST-CAT
    Cat.bestCat = tom;
    System.out.println(tom.state());
    // Output : BEST-CAT
  }

}

Lớp mèo:

public class Cat {

  static Cat bestCat;

  public Cat() {
    super();
  }

  public String state() {
      return ((this == Cat.bestCat) ? "BEST-CAT" : "NOT-BEST-CAT");
  }

}

Tôi đã được truyền cảm hứng bởi @tbodt.


1
Tôi biết đó không phải là môn đánh gôn, nhưng bạn nhận ra rằng bạn có thể loại bỏ hàm tạo và nó vẫn như vậy, phải không?
David Conrad

2
Đây không phải là "một đối tượng có trạng thái thay đổi khi gán". Đây là bạn thao túng một giá trị toàn cầu và sau đó in một cái gì đó dựa trên nó. Nó không khác gì Cat.x = 2và sau đó in Cat.x.
Chris Hayes

@Chris - Trạng thái đối tượng dựa trên giá trị toàn cầu của Google. Vì vậy, trạng thái đối tượng thay đổi trên bài tập. Câu hỏi nêu rõ ;-) rằng trạng thái có thể là một phương pháp xác định, không xác định. Phương thức của tôi () là một phương thức như vậy.
Nicolas Barbulesco

Không, trạng thái đối tượng thay đổi trên nhiệm vụ cụ thể này . Nếu tôi làm Cat otherCat = tomnhà nước sẽ không thay đổi gì cả. Tôi có một thời gian khó tin rằng điều này đáp ứng thư hoặc tinh thần của các quy tắc.
Chris Hayes

@Chris - Tất nhiên đối tượng thay đổi trong nhiệm vụ này! Câu hỏi yêu cầu một đối tượng có trạng thái được thay đổi bởi bài tập. Không cho một đối tượng có trạng thái được thay đổi bởi bất kỳ nhiệm vụ.
Nicolas Barbulesco

3

C ++

Hành vi này thực sự được chỉ định trong tiêu chuẩn (và đó là lý do tại sao nó bị phản đối).

#include<iostream>
#include<memory>
int main()
{
    std::auto_ptr<int> a(new int(0));
    std::cout<<a.get()<<'\n';
    std::auto_ptr<int> b = a;
    std::cout<<a.get()<<'\n';
}

Đầu ra

some address
0

Quá trình gây ra điều này giống như câu trả lời của Abhijit nhưng không yêu cầu std::movevà giống như câu trả lời của bến du thuyền mà sử dụng một lớp tiêu chuẩn thay vì tự xác định nó.

Chỉnh sửa: Tôi đang thêm một số lời giải thích. Trong đầu ra, "một số địa chỉ" thực sự sẽ là một giá trị hex cho địa chỉ của số nguyên được phân bổ. std::auto_ptrgiải phóng con trỏ cửa hàng của nó khi được gán cho người khác auto_ptrvà đặt con trỏ bên trong của nó thành 0. Gọi get()để truy cập vào con trỏ cửa hàng.


Tôi nghi ngờ rằng "đầu ra" ở đây không phải là đầu ra thực sự.
Nicolas Barbulesco

Bạn có thể giải thích những gì được cho là phải làm gì? Đặc biệt là phương pháp get()? Tại sao nó sẽ trả về 0 vào cuối?
Nicolas Barbulesco

@Nicholas vâng. Đầu ra này không phải là đầu ra thực sự, mà là đầu ra tổng quát hơn (tôi cũng không có quyền truy cập vào trình biên dịch nên tôi không có ví dụ về địa chỉ hợp lệ tại thời điểm đó).
JKor

1
Hừm, cái này không biên dịch được trên gcc 4.8.
Michael Hampton

1
Tôi đã sửa các lỗi biên dịch. Vẫn có những cảnh báo nếu bạn đang biên dịch cho c ++ 11 vì auto_ptrkhông được dùng nữa.
JKor

3

Con trăn

import sys
class K:state = property(sys.getrefcount)

2

Python 2.x

Tôi không thể tìm thấy một cách thích hợp để làm điều này mà không cần xác định một lớp học thêm.

class State(object):
    def __init__(self):
        self.state = 0
    def __set__(self, obj, other):
        # Keep different references
        other.state += 1
        self.state += 2

class Program(object):
    obj, value = State(), State() # Create two State-objects
    def __init__(self):
        print "Before assignment:", self.obj.state, self.value.state # 0 0
        self.value = self.obj # Set value to obj (supposedly)
        print "After  assignment:", self.obj.state, self.value.state # 1 2
        self.value = self.obj
        print "2nd    assignment:", self.obj.state, self.value.state # 2 4

Program()

2

Java

Tất cả các giải pháp khác sử dụng hình thức quá tải toán tử ngôn ngữ của họ. Java không có quá tải toán tử, vì vậy tôi nghĩ rằng tôi đã bị mắc kẹt. Nhưng tôi đã nghĩ ra một cái gì đó.

Đây là lớp chính:

public class Program {
    public static void main(String[] args) {
        Thing thing = new Thing(0);
        System.out.println(thing.getState());
        Thing.otherThing = thing;
        Thread.sleep(1);
        System.out.println(thing.getState());
    }
}

Có một vài dòng đáng ngờ, nhưng họ sẽ không làm gì nếu Thinglớp học hoàn toàn bình thường. Nó không phải là:

public class Thing {
    private int state;

    public Thing(int state) {
        this.state = state;
    }

    public int getState() {
        return state;
    }

    // Please do your best to ignore the rest of this class.
    public static volatile Thing otherThing;
    static {
        Thread t = new Thread() {
            public void run() {
                Thing t = otherThing;
                while (true)
                    if (t != otherThing) {
                        t = otherThing;
                        t.state++;
                    }
            }
        };
        t.setDaemon(true);
        t.start();
    }
}

Nó không được đảm bảo để hoạt động vì các luồng, nhưng tôi đã thử nghiệm nó trên JDK 1.8u5 và nó hoạt động ở đó.



@KyleKanos Đã loại bỏ tất cả các ký tự unicode> U + 00FF
tbodt

1

Lisp thường gặp

Tôi định nghĩa trạng thái là số lượng các biến đặc biệt liên kết với một vectơ. Vì vậy, gán cho một biến đặc biệt thay đổi trạng thái.

(defgeneric state (object)
  (:documentation "Get the state of this object."))

(defmethod state ((object vector))
  ;; The state of a vector is the number of symbols bound to it.
  (let ((count 0))
    ;; Iterate each SYM, return COUNT.
    (do-all-symbols (sym count)
      ;; When SYM is bound to this vector, increment COUNT.
      (when (and (boundp sym) (eq (symbol-value sym) object))
    (incf count)))))

(defparameter *a* #(this is a vector))
(defparameter *b* nil)
(defparameter *c* nil)

(print (state *a*))
(setf *b* *a*)
(print (state *a*))
(print (state *a*))
(setf *c* *a*)
(print (state *a*))

Đầu ra:

1 
2 
2 
3 

Nó chỉ hoạt động với các bài tập cho các biến đặc biệt, không phải cho các biến từ vựng, cũng không cho các vị trí trong một đối tượng.

Coi chừng do-all-symbolstrông trong tất cả các gói, vì vậy nó bỏ lỡ các biến không có gói. Nó có thể nhân đôi số ký hiệu tồn tại trong nhiều gói (khi một gói nhập ký hiệu từ gói khác).

Hồng ngọc

Ruby gần như giống nhau, nhưng tôi định nghĩa trạng thái là số hằng liên quan đến một mảng.

class Array
  # Get the state of this object.
  def state
    # The state of an array is the number of constants in modules
    # where the constants refer to this array.
    ObjectSpace.each_object(Module).inject(0) {|count, mod|
      count + mod.constants(false).count {|sym|
        begin
          mod.const_get(sym, false).equal?(self)
        rescue NameError
          false
        end
      }
    }
  end
end

A = %i[this is an array]
puts A.state
B = A
puts A.state
puts A.state
C = A
puts A.state

Đầu ra:

state-assign.rb:9:in `const_get': Use RbConfig instead of obsolete and deprecated Config.
1
2
2
3

Đây là một khái quát về câu trả lời của histocrat cho các đối tượng Ruby không phải là các lớp hoặc mô-đun. Cảnh báo xuất hiện vì hằng số Cấu hình tự động tải một số mã tạo cảnh báo.


0

C ++

Kết quả có thể khác nhau trong các nền tảng khác nhau. Đã thử nghiệm trên ideone .

#include <iostream>
#include <cassert>
// File format: [ciiiiciiii...] a char (1 byte) followed by its state (4 bytes)
// Each group takes 5 bytes
char Buffer[30]; // 5*6, six groups

struct Group {
    char c;
    int state;
};

int main(void) {
    assert(sizeof(char) == 1);
    assert(sizeof(int) == 4);

    Group& first_group = *(Group*)(&Buffer[0]); // Group 1 is at 0
    Group& second_group = *(Group*)(&Buffer[5]); // Group 2 is at 5

    first_group.c = '2';
    first_group.state = 1234;

    std::cout << first_group.state << std::endl;

    second_group = first_group;

    std::cout << first_group.state << std::endl;

    return 0;
}

Đầu ra:

1234
13010

0

C #

class A
{
    public int N { get; set; }
    public override string ToString() { return N.ToString(); }
}
class B
{
    public int N { get; set; }
    public override string ToString() { return N.ToString(); }
    public static implicit operator A(B b) { b.N = -b.N; return new A { N = b.N }; }
}
public static void Test()
{
    A a = new A { N = 1 };
    B b = new B { N = 2 };
    Console.WriteLine("a is {0}, b is {1}", a, b);
    Console.WriteLine("a is {0}, b is {1}", a, b);
    a = b;
    Console.WriteLine("a is {0}, b is {1}", a, b);
    Console.WriteLine("a is {0}, b is {1}", a, b);
}

Đầu ra:

a is 1, b is 2
a is 1, b is 2
a is -2, b is -2
a is -2, b is -2

Cái này làm gì Đây có phải là quá tải các nhà điều hành =?
Nicolas Barbulesco

@Nicolas Không chính xác. Đó là khi truyền từ a Bsang an A, bởi vì nó implicit operator A(B b)có tác dụng phụ.
ClickRick
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.