Never Redefine an inherited nonvirtual function

Hi, recently I was wondering what happens underneath during compile time
when running the code below.

why is the function of class B not called?
Is it because you have two clashing definitions and one overrides the other?

I thought "A * ptr" was just a declaration
why is it when I allocate a B object and call it`s function
it even knows about the function of A. What do I read to
understand more?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  #include <iostream>


class A {
public:


	void foo()
	{
		std::cout << "This is A \n";
	}


};


class B : public A{
public:

	

	void foo()
	{
		std::cout << "This is B \n";
	}



};

int main()
{

	A * ptr = new B();

	ptr->foo();
	system("pause");

}



Many thanks,
Phil
The compiler only looks at the type of the pointer when deciding which function to call.

ptr is a A* so ptr->foo() will call A::foo().
Ok then why is the constructor of B called in this case?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 #include <iostream>


class A {
public:

	A()
	{
				std::cout << "This is A CTR \n";
	}

	void foo()
	{
		std::cout << "This is A \n";
	}

};


class B : public A{
public:

	B()
	{
				std::cout << "This is B CTR \n";
	}

	void foo()
	{
		std::cout << "This is B \n";
	}



};

int main()
{

	A * ptr = new B();

	ptr->foo();
	system("pause");

}
new B(); is explicit call to constructor. It returns address of type B object.

You then store the address into ptr, which is pointer-to-A. Implicit conversion from B* ta A* is possible, because B is-a A by inheritance.
That`s insightful thank you both,

Last question why does this work, should it not throw a compiler error
due to implicitly converting float to int?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54


 #include <iostream>


class A {
public:

	 A()
	{
				std::cout << "This is A CTR \n";
	}
	 
	void foo()
	{
		std::cout << "This is A \n";
	}

};


 class B : public A{
public:

	explicit B(int a)
	{
				std::cout << "This is value A = " << a << std::endl;
	}

	explicit B()
	{
				std::cout << "This is B CTR \n";
	}

	void foo()
	{
		std::cout << "This is B \n";
	}



};

int main()
{

	A * ptr = new B(1.5f);

	ptr->foo();
	system("pause");

}

In C++ implicitly conversion from float to int is allowed. Some compilers could give you a warning though.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void foo( int ) {}

int main()
{
    foo( 1.2f ) ; // fine: implicit conversion from float to int
    
    foo( { 1.2f } ) ; // *** error: narrowing conversion

    const unsigned long long a = 1234 ;
    foo( {a} ) ; // fine: compile-time constant within the range of 'int', not narrowing

    unsigned long long b = 1234 ;
    foo( {b} ) ; // *** error: narrowing conversion
}

See: http://www.stroustrup.com/C++11FAQ.html#narrowing
All clear.
Thanks everyone !
Topic archived. No new replies allowed.