简体   繁体   中英

How to deprecate function when return type changes c++

What strategies are there for deprecating functions when their return type needs to change? For example, I have:

BadObject foo(int); // Old function: BadObject is being removed. 
Object    foo(int); // New function. 

Object and BadObject are very different internally, and swapping their return types will break code for current users of my library. I'm aiming to avoid that.

I can mark BadObject foo(int) deprecated , and give users time to change affected code.
However, I can't overload foo based on return-type . foo is very well named, and it doesn't need to take extra parameters. How can I add the new function to my library whilst maintaining the old version, at least for a while?

What's the strategy to deprecate the old function without breaking too much dependant code, while providing users the time to migrate to the new version? Ideally I'd keep the current function name and parameter list, because it's named quite well now. It feels like this should be a reasonably common problem: what's a decent way to solve it?

Although the solution will force you to change your function names, but it'll be a compromise between your old users and your new ones.

So - rename the old foo into deprecatedFoo and your new foo into foo2 (or anything you want). Then, in the header file you include with your library, you can simply:

#define deprecatedFoo foo

and inside the function itself do:

#warning ("This function is deprecated. Use 'foo2' or change the #define in LINE in file HEADER.")

Users of the old versions won't have to change their code, and will be issued a warning, and the new users will probably listen and change the #define in order to use the new foo .

In the next version you'll just delete the old foo and the define .

I think a classic example is Boost's Spirit .

From their FAQ :

While introducing Spirit V2 we restructured the directory structure in order to accommodate two versions at the same time. All of Spirit.Classic now lives in the directory

boost/spirit/home/classic

where the directories above contain forwarding headers to the new location allowing to maintain application compatibility. The forwarding headers issue a warning (starting with Boost V1.38) telling the user to change their include paths. Please expect the above directories/forwarding headers to go away soon.

This explains the need for the directory

boost/spirit/include

which contains forwarding headers as well. But this time the headers won't go away. We encourage application writers to use only the includes contained in this directory. This allows us to restructure the directories underneath if needed without worrying application compatibility. Please use those files in your application only. If it turns out that some forwarding file is missing, please report this as a bug.

You can ease migration by keeping the new and old versions in separate directories and using forwarding headers to maintain compatibility. Users will eventually be forced to use the new headers.

SDL 2.0 has a different approach. They don't provide a compatibility layer but instead a migration guide walking the users through the most dramatic changes. In this case, you can help users understand how they need to restructure their code.

What if to make your Object class inherit from BadObject (which you'll keep temporarily)? Then the old user code won't know about that, so it won't break provided that your new "foo" function still returns your objects correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM