LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-16-2012, 05:04 AM   #1
JohnGraham
Member
 
Registered: Oct 2009
Posts: 467

Rep: Reputation: 139Reputation: 139
Constructor takes string => constructor not called...? (C++)


Hi there,

I have a File class and I want to call its constructor. It has three constructors, they look like this:

Code:
File(int fd = -1);                    // Construct from file descriptor...
File(const std::string &name, Mode);  // ...from file name + open mode...
File(const File &file);               // ...or from other descriptor.
In a simple program (that at the moment just opens a file to see if it is there) I accidentally called it with just a string argument - i.e.:

Code:
// Using just "File file(argv[1])" seemed to want to use the
// constructor that takes an int.
File file(std::string(argv[1]));
I got no compile-time error, and the output of nm shows no symbol relating to the File class is used (i.e. the output of "nm program|grep File"). When the program was run, no exception was thrown if the file didn't exist, as I would have expected.

When I change the call to:

Code:
File file(std::string(argv[1]), File::RdOnly);
I get both (i) the symbols for the appropriate constructor and destructor in the output file and (ii) the correct behaviour (i.e. an exception being thrown) if the file doesn't exist.

Can anybody tell me what's going on here?
 
Old 02-16-2012, 08:22 AM   #2
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Do you have a derived class with File as a base containing a constructor that takes a single std::string argument? You might try declaring all of your constructors (other than default and copy) explicit.
Kevin Barry
 
Old 02-16-2012, 10:17 AM   #3
JohnGraham
Member
 
Registered: Oct 2009
Posts: 467

Original Poster
Rep: Reputation: 139Reputation: 139
Thanks for the suggestion - no, the only derived class is Socket and that has no such constructor. Also, File does not derive from any class. Still, declaring the instance like "File file(/* args */)" surely should never cause any other constructor to be called, derived or otherwise, should it?
 
Old 02-16-2012, 10:42 AM   #4
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by JohnGraham View Post
Can anybody tell me what's going on here?
You are declaring a function with this statement (sort of what one would do in C using the extern keyword):
Code:
File file(std::string(argv[1]));
The function, called file(), accepts a pointer to an std::string argument, and returns a File object.

I wish I could offer a better explanation on how to avoid errors like this; as you discovered, the compiler does not issue any warning/error. Try calling the function file() with an std::string parameter, and then you will get the error.

Play with the code that is commented out:
Code:
#include <string>
#include <iostream>

typedef int Mode;

class File
{
public:
    File(int fd = -1)
    {
        std::cout << "File constructor for fd called." << std::endl;
    }

    File(const std::string& name, Mode mode)
    {
        std::cout << "File constructor for name and mode called." << std::endl;
    }

    File(const File& other)
    {
        std::cout << "File copy constructor." << std::endl;
    }

    ~File()
    {
        std::cout << "File destructor called." << std::endl;
    }
};

int main(int argc, char** argv)
{
    File file(std::string(argv[1]));

    std::string foo = "foo";
    //file(&foo);
}


File file(std::string* s)
{
    std::cout << "file() called with string " << s << "." << std::endl;

    return File();
}

Last edited by dwhitney67; 02-16-2012 at 10:45 AM.
 
Old 02-16-2012, 12:37 PM   #5
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by dwhitney67 View Post
You are declaring a function with this statement (sort of what one would do in C using the extern keyword):
Code:
File file(std::string(argv[1]));
The function, called file(), accepts a pointer to an std::string argument, and returns a File object.
To me it makes very little sense that in this context std::string(argv[1]) is the same as std::string argv[1], but that appears to be the case. I actually had to look it up, and indeed this exact type of ambiguity is addressed in C++03 §8.2.1. What's more annoying is this (see 8.2.7):
Code:
struct F
{
	F(int) {}
};

struct A;

namespace X {
struct B;
}

int main()
{
	F func1(int(A));
	F func2(int(B));

	char A;
	using X::B;

	F func1(int(B));
	F func2(int(A));

	func1(0); //<-- ambiguous
	func2(0); //<-- 'func2' isn't overloaded
}
Code:
test.cpp: In function 'int main()':
test.cpp:23:9: error: call of overloaded 'func1(int)' is ambiguous
test.cpp:14:4: note: candidates are: F func1(int (*)(A))
test.cpp:20:4: note:                 F func1(int (*)(X::B))
Kevin Barry
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
C++ constructor/copy constructor issues in g++ 3.4.6 abhinav.dube15 Programming 7 03-13-2011 08:27 AM
Shared object constructor not called when library loaded adevi003 Programming 2 10-12-2009 04:51 AM
Class constructor not being called ChimpFace9000 Programming 1 06-03-2002 08:54 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:00 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration