| // This file illustrates the cross language polymorphism using directors. |
| |
| package main |
| |
| import ( |
| . "./example" |
| "fmt" |
| ) |
| |
| func main() { |
| // Create an instance of CEO, a class derived from the Go |
| // proxy of the underlying C++ class. The calls to getName() |
| // and getPosition() are standard, the call to getTitle() uses |
| // the director wrappers to call CEO.getPosition(). |
| e := NewCEO("Alice") |
| fmt.Println(e.GetName(), " is a ", e.GetPosition()) |
| fmt.Println("Just call her \"", e.GetTitle(), "\"") |
| fmt.Println("----------------------") |
| |
| // Create a new EmployeeList instance. This class does not |
| // have a C++ director wrapper, but can be used freely with |
| // other classes that do. |
| list := NewEmployeeList() |
| |
| // EmployeeList owns its items, so we must surrender ownership |
| // of objects we add. |
| // e.DisownMemory() |
| list.AddEmployee(e) |
| fmt.Println("----------------------") |
| |
| // Now we access the first four items in list (three are C++ |
| // objects that EmployeeList's constructor adds, the last is |
| // our CEO). The virtual methods of all these instances are |
| // treated the same. For items 0, 1, and 2, all methods |
| // resolve in C++. For item 3, our CEO, GetTitle calls |
| // GetPosition which resolves in Go. The call to GetPosition |
| // is slightly different, however, because of the overridden |
| // GetPosition() call, since now the object reference has been |
| // "laundered" by passing through EmployeeList as an |
| // Employee*. Previously, Go resolved the call immediately in |
| // CEO, but now Go thinks the object is an instance of class |
| // Employee. So the call passes through the Employee proxy |
| // class and on to the C wrappers and C++ director, eventually |
| // ending up back at the Go CEO implementation of |
| // getPosition(). The call to GetTitle() for item 3 runs the |
| // C++ Employee::getTitle() method, which in turn calls |
| // GetPosition(). This virtual method call passes down |
| // through the C++ director class to the Go implementation |
| // in CEO. All this routing takes place transparently. |
| fmt.Println("(position, title) for items 0-3:") |
| fmt.Println(" ", list.Get_item(0).GetPosition(), ", \"", list.Get_item(0).GetTitle(), "\"") |
| fmt.Println(" ", list.Get_item(1).GetPosition(), ", \"", list.Get_item(1).GetTitle(), "\"") |
| fmt.Println(" ", list.Get_item(2).GetPosition(), ", \"", list.Get_item(2).GetTitle(), "\"") |
| fmt.Println(" ", list.Get_item(3).GetPosition(), ", \"", list.Get_item(3).GetTitle(), "\"") |
| fmt.Println("----------------------") |
| |
| // Time to delete the EmployeeList, which will delete all the |
| // Employee* items it contains. The last item is our CEO, |
| // which gets destroyed as well and hence there is no need to |
| // call DeleteCEO. |
| DeleteEmployeeList(list) |
| fmt.Println("----------------------") |
| |
| // All done. |
| fmt.Println("Go exit") |
| } |