#how to convert this c++ to typescript?

1 messages ยท Page 1 of 1 (latest)

dapper tide
#
// deriv_VirtualFunctions2.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
class Base {
public:
  virtual void NameOf();  // Virtual function.
  void InvokingClass();  // Nonvirtual function.
};
// Implement the two functions.
void Base::NameOf() {
  cout << "Base::NameOf\n";
}
void Base::InvokingClass() {
  cout << "Invoked by Base\n";
}
class Derived : public Base {
public:
  void NameOf();  // Virtual function.
  void InvokingClass();  // Nonvirtual function.
};
// Implement the two functions.
void Derived::NameOf() {
  cout << "Derived::NameOf\n";
}
void Derived::InvokingClass() {
  cout << "Invoked by Derived\n";
}
int main() {
  // Declare an object of type Derived.
  Derived aDerived;

  // Declare two pointers, one of type Derived * and the other
  // of type Base *, and initialize them to point to aDerived.
  Derived *pDerived = &aDerived;
  Base  *pBase  = &aDerived;
  // Call the functions.
  pBase->NameOf();      // Call virtual function.
  pBase->InvokingClass();  // Call nonvirtual function.
  pDerived->NameOf();    // Call virtual function.
  pDerived->InvokingClass(); // Call nonvirtual function.
}

correct c++ output:

Derived::NameOf
Invoked by Base
Derived::NameOf
Invoked by Derived

I have tried but failed, please help me.

class Base {
    // Abstract function
    nameOf(): void {
        console.log("Base::nameOf");
    }

    invokingClass(): void {
      console.log("Invoked by Base");
    }
}

class Derived extends Base {
    nameOf(): void {
        console.log("Derived::nameOf");
    }

    invokingClass(): void {
      console.log("Invoked by Derived");
    }
}

const aDerived = new Derived();
const pDerived = aDerived;
const pBase: Base = aDerived;

pBase.nameOf();
(pBase as Base).invokingClass();
pDerived.nameOf();
pDerived.invokingClass();

These typescript output wrong result:

"Derived::nameOf" 
"Invoked by Derived" 
"Derived::nameOf" 
"Invoked by Derived"
stoic mantle
#

There is no such thing as a nonvirtual function in JS

#

all functions are effectively virtual by C++ nomenclature

#

which imo is a good thing

#

The only real advantage of nonvirtual functions in C++ that I can think of is performance, since you're skipping the vtable indirection

#

But that already goes out the window because you are using JavaScript

prime jetty
#

well, it's not like nonvirtual functions are even possible in JS

prime jetty
stoic mantle
#

Yes exactly

#

But you can of course simulate nonvirtual functions by just using a different function name lol

#

Because nonvirtual calls are resolved at compile time anyway so it's effectively equivalent to calling a function with a different name

#

(~> mangling)

prime jetty
#

or using Class.prototype.method.call(derived)

#

:D

stoic mantle
#

Yeah, that's possible indeed

#

That would probably be the closest thing to a nonvirtual call

#

But very unidiomatic

prime jetty
#

nah, not really

#

i think it's pretty common

stoic mantle
#

Hm, guess it's just something I would personally avoid then

#

But I barely write OOP code anyway ๐Ÿ˜„

prime jetty
#

[].concat.call and the like are pretty common

stoic mantle
#

Yes, and I tend to avoid those as well ๐Ÿ˜›

#

Actually, wait what? I've never seen that specific statement

late pulsar
#

also @dapper tide you should take some time to understand what the typescript compiler does (and more philosophically, what typescript is). the compiler's output is not type-directed like in C++. instead your types are merely checked then erased and the result is the compiled JS

in your code for example if you look at the compiler output you'll see the part at the end looks like this:

const aDerived = new Derived();
const pDerived = aDerived;
const pBase = aDerived;
pBase.nameOf();
pBase.invokingClass();
pDerived.nameOf();
pDerived.invokingClass();

your as Base is just totally gone and could never have an influence on the runtime behavior

you instead need to write runtime code to change which class's method is called. for example @prime jetty mentioned using .call. applying that to your code could look like this:

const p = new Derived();

p.nameOf();
Base.prototype.invokingClass.call(p);
p.nameOf();
p.invokingClass();
dapper tide
#

@everyone have alternative solution? before I have read a book about typescript to demonstrate these examples, but I forget, oh my god. that book seems not to use this practice.

late pulsar
#

i suggested a solution at the end of my last message